質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

参照

参照は、プログラミングにおいて変数や関数といったメモリ空間上での所在を指示するデータのことを指します。その中にはデータ自体は含まれず、他の場所にある情報を間接的に指示するプログラムです。

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

944閲覧

c言語 多次元配列へのポインタを参照するとセグフォする

hidekiti

総合スコア23

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

参照

参照は、プログラミングにおいて変数や関数といったメモリ空間上での所在を指示するデータのことを指します。その中にはデータ自体は含まれず、他の場所にある情報を間接的に指示するプログラムです。

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2021/09/07 07:20

環境

  • xubuntu
  • gcc (Debian 8.3.0-6) 8.3.0

セグフォするソースコード

tlwelv0_encrypto_torusをksk_constructの内部から呼び出したときにセグフォします。。
原因がわからないです。。ksk_constructから渡している多次元配列へのポインタが問題なんだとは思っています。
助けてください。

c

1#include "c_hom_nand.h" 2 3#include <math.h> 4#include <stdlib.h> 5#include <string.h> 6 7#define REP(ident, count) for (int ident = 0; ident < count; ident++) 8#define rREP(ident, count) for (int ident = count - 1; ident >= 0; ident--) 9 10#pragma region math helper 11// in [0,1] 12f64 rand_uniform() { return ((f64)random() + 1) / ((f64)RAND_MAX + 1); } 13f64 rand_normal(f64 m, f64 s) { 14 f64 z = sqrt(-2.0 * log(rand_uniform())) * sin(2.0 * M_PI * rand_uniform()); 15 return m + s * z; 16} 17binary_t randb_uniform() { return rand_uniform() > 0.5 ? bin_one : bin_zero; } 18torus_t randt_uniform() { return double2torus(rand_uniform()); } 19torus_t randt_normal(f64 m, f64 s) { return double2torus(rand_normal(m, s)); } 20// l*bits <= TORUS_BIT 21void torus_decomp_u32(torus_t t, int bits, int l, u32 *out) { 22 t += 1 << (TORUS_BIT - l * bits - 1); 23 REP(i, l) { 24 out[i] = (t >> (TORUS_BIT - bits * (i + 1))) & ((1 << bits) - 1); 25 } 26} 27void torus_decomp_i32(torus_t t, int bits, int l, i32 *out) { 28 u32 mem[l]; 29 torus_decomp_u32(t, bits, l, mem); 30 int bg = 1 << bits; 31 rREP(i, l) { 32 if (2 * mem[i] > bg) { 33 if (i > 0) mem[i - 1] += 1; 34 out[i] = mem[i] - bg; 35 } 36 out[i] = mem[i]; 37 } 38} 39#pragma endregion 40 41torus_t double2torus(f64 d) { return (torus_t)(fmod(d, 1.0) * TORUS_BIT_MAX); } 42torus_t float2torus(f32 f) { return (torus_t)(fmod(f, 1.0) * TORUS_BIT_MAX); } 43f64 torus2double(torus_t t) { return ((f64)t) / (f64)TORUS_BIT_MAX; } 44f32 torus2float(torus_t t) { return ((f32)t) / (f32)TORUS_BIT_MAX; } 45torus_t binary2torus(binary_t b) { 46 return double2torus((2 * b - 1) * 1.0 / 8.0); 47} 48binary_t torus2binary(torus_t t) { return (binary_t)(torus2double(t) <= 0.5); } 49 50void tlwelv0_encrypto_torus(const tlwelv0_skey_t *skey, torus_t t, 51 tlwelv0_t *out) { 52 REP(i, TLWE_N) out->pkey[i] = randt_uniform();// ここでセグフォ out->pkeyがやばいっぽい 53 torus_t e = randt_normal(0, TLWE_ALPHA); 54 out->cipher = t + e; 55 REP(i, TLWE_N) out->cipher += out->pkey[i] * (*skey)[i]; 56} 57void tlwelv0_decrypto_torus(tlwelv0_t *tlwe, const tlwelv0_skey_t *skey, 58 torus_t *out) { 59 *out = tlwe->cipher; 60 REP(i, TLWE_N) *out -= tlwe->pkey[i] * (*skey)[i]; 61} 62void tlwelv1_encrypto_torus(const tlwelv1_skey_t *skey, torus_t t, 63 tlwelv1_t *out) { 64 REP(i, TRLWE_N) out->pkey[i] = randt_uniform(); 65 torus_t e = randt_normal(0, TLWE_ALPHA); 66 out->cipher = t + e; 67 REP(i, TRLWE_N) out->cipher += out->pkey[i] * (*skey)[i]; 68} 69void tlwelv1_decrypto_torus(tlwelv1_t *tlwe, const tlwelv1_skey_t *skey, 70 torus_t *out) { 71 *out = tlwe->cipher; 72 REP(i, TRLWE_N) *out -= tlwe->pkey[i] * (*skey)[i]; 73} 74 75void ksk_construct(kskey_t *ksk, const tlwelv1_skey_t *lv1_skey, 76 const tlwelv0_skey_t *lv0_skey) { 77 REP(i, TRLWE_N) { 78 REP(l, IKS_L) { 79 REP(t, IKS_T) { 80 tlwelv0_encrypto_torus( 81 lv0_skey, 82 double2torus((*lv1_skey)[i] * (t + 1) * 83 pow(0.5, IKS_BASEBIT * (l + 1))), 84 ksk[i][l][t]); 85 } 86 } 87 } 88} 89// must:: t > 0 , t==0 => ksk is zero 90const tlwelv0_t *ksk_get(const kskey_t *key, int i, int l, int t) { 91 return key[i][l][t - 1]; 92} 93 94void identity_key_swtich(const tlwelv1_t *lv1, const kskey_t *ksk, 95 tlwelv0_t *out) { 96 out->cipher = lv1->cipher; 97 memset(out->pkey, 0, sizeof(out->pkey)); 98 REP(i, TRLWE_N) { 99 u32 mem[IKS_L]; 100 torus_decomp_u32(lv1->pkey[i], IKS_BASEBIT, IKS_L, mem); 101 REP(l, IKS_L) { 102 if (mem[l] != 0) { 103 const tlwelv0_t *key = ksk_get(ksk, i, l, mem[l]); 104 105 out->cipher -= key->cipher; 106 REP(j, TLWE_N) out->pkey[j] -= key->pkey[j]; 107 } 108 } 109 } 110}

header

1typedef unsigned int u32; 2typedef int i32; 3typedef float f32; 4typedef double f64; 5 6#define BLIND_ROTATE_BIT 10 7#define TLWE_N 645 8#define TRGSW_BGBIT 6 9#define TRGSW_L 3 10#define TRLWE_ALPHA_BIT 25 11#define TLWE_ALPHA_BIT 15 12#define IKS_L 8 13#define IKS_BASEBIT 2 14 15#define TLWE_ALPHA 1.0 / (double)(1 << TLWE_ALPHA_BIT) 16#define TRLWE_N 1 << BLIND_ROTATE_BIT 17#define TRLWE_ALPHA 1.0 / (double)(1 << TRLWE_ALPHA_BIT) 18#define TRGSW_BG 1 << TRGSW_BGBIT 19#define IKS_T 1 << IKS_BASEBIT 20 21#pragma region math helper 22// in [0,1] 23f64 rand_uniform(); 24f64 rand_normal(f64 mu, f64 sigma); 25#pragma endregion 26 27typedef enum { 28 bin_zero = 0, 29 bin_one = 1, 30} binary_t; 31typedef u32 torus_t; 32#define TORUS_BIT 32 33#define TORUS_BIT_MAX 0xffffffff 34torus_t double2torus(f64 d); 35torus_t float2torus(f32 f); 36f64 torus2double(torus_t t); 37f32 torus2float(torus_t t); 38torus_t binary2torus(binary_t b); 39binary_t torus2binary(torus_t t); 40 41binary_t randb_uniform(); 42 43typedef binary_t tlwelv0_skey_t[TLWE_N]; 44typedef struct TLWElv0 tlwelv0_t; 45struct TLWElv0 { 46 torus_t cipher; 47 torus_t pkey[TLWE_N]; 48}; 49void tlwelv0_encrypto_torus(const tlwelv0_skey_t *skey, torus_t t, 50 tlwelv0_t *out); 51void tlwelv0_decrypto_torus(tlwelv0_t *tlwe, const tlwelv0_skey_t *skey, 52 torus_t *out); 53 54typedef binary_t tlwelv1_skey_t[TRLWE_N]; 55typedef struct TLWElv1 tlwelv1_t; 56struct TLWElv1 { 57 torus_t cipher; 58 torus_t pkey[TRLWE_N]; 59}; 60void tlwelv1_encrypto_torus(const tlwelv1_skey_t *skey, torus_t t, 61 tlwelv1_t *out); 62void tlwelv1_decrypto_torus(tlwelv1_t *tlwe, const tlwelv1_skey_t *skey, 63 torus_t *out); 64 65typedef struct TLWElv0 kskey_t[TRLWE_N][IKS_L][IKS_T]; 66void ksk_construct(kskey_t *ksk, const tlwelv1_skey_t *lv1_skey, 67 const tlwelv0_skey_t *lv0_skey); 68// must:: t > 0 , t==0 => ksk is zero 69const tlwelv0_t *ksk_get(const kskey_t *key, int i, int l, int t); 70void identity_key_swtich(const tlwelv1_t *lv1, const kskey_t *ksk, 71 tlwelv0_t *out); 72 73typedef binary_t trlwe_skey_t[TRLWE_N]; 74typedef struct TRLWE trlwe_t; 75struct TRLWE { 76 torus_t cipher[TRLWE_N]; 77 torus_t pkey[TRLWE_N]; 78}; 79 80typedef struct TRGSW trgsw_t; 81struct TRGSW { 82 torus_t cipher[TRLWE_N][TRGSW_L * 2]; 83 torus_t pkey[TRLWE_N][TRGSW_L * 2]; 84}; 85 86typedef struct TRGSW bskey_t[TLWE_N]; 87typedef struct TFHE tfhe_t; 88struct TFHE { 89 bskey_t bsk; 90 kskey_t ksk; 91}; 92tlwelv0_t tfhe_nand(tlwelv0_t *i_0, tlwelv0_t *i_1); 93

main.c

1#include <assert.h> 2#include <math.h> 3#include <stdio.h> 4#include <stdlib.h> 5 6#include "c_hom_nand.h" 7 8int main() { 9 { 10 binary_t s_key_lv1[TRLWE_N]; 11 for (int i = 0; i < TRLWE_N; i++) s_key_lv1[i] = randb_uniform(); 12 binary_t s_key_lv0[TLWE_N]; 13 for (int i = 0; i < TLWE_N; i++) s_key_lv0[i] = randb_uniform(); 14 15 kskey_t *ksk= malloc(sizeof(kskey_t)); 16 ksk_construct(ksk, &s_key_lv1, &s_key_lv0); 17 18 { 19 binary_t b = bin_zero; 20 torus_t item = binary2torus(b); 21 tlwelv1_t lv1; 22 tlwelv1_encrypto_torus(&s_key_lv1, item, &lv1); 23 tlwelv0_t lv0; 24 identity_key_swtich(&lv1, ksk, &lv0); 25 torus_t rest; 26 tlwelv0_decrypto_torus(&lv0, &s_key_lv0, &rest); 27 binary_t resb = torus2binary(rest); 28 assert(resb == b); 29 } 30 31 { 32 binary_t b = bin_one; 33 torus_t item = binary2torus(b); 34 tlwelv1_t lv1; 35 tlwelv1_encrypto_torus(&s_key_lv1, item, &lv1); 36 tlwelv0_t lv0; 37 identity_key_swtich(&lv1, ksk, &lv0); 38 torus_t rest; 39 tlwelv0_decrypto_torus(&lv0, &s_key_lv0, &rest); 40 binary_t resb = torus2binary(rest); 41 assert(resb == b); 42 } 43 } 44}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2021/09/07 07:27 編集

一行のコメントもない250行のコードをどかっと乗っけて「原因がわからないです」と申されましてもねぇ... 回答者は超能力も霊力も持ち合わせてはいませんよ。デバッガは何と言ってるんですか?
hidekiti

2021/09/07 08:15

加筆依頼ありがとうございます。要点の部分だけ抜き取ろうかとも思ったのですが、うまく抜き取れなさそうでそのまま上げさせていただきました。 gdbは上記コードのコメントの部分でセグフォであることしか教えてくれず途方に暮れてました。coreファイルを見ても不慣れでデバッガーの出力以上のことは分からず、いろいろ試した結果、kskへのアクセスが問題そうだと思いました。 これについてはおそらく久し振りにcを書いた自分の型についての考え違いだと思った次第です。
guest

回答1

0

ベストアンサー

c

1 REP(i, TRLWE_N) { 2 REP(l, IKS_L) { 3 REP(t, IKS_T) { 4 tlwelv0_encrypto_torus( 5 lv0_skey, 6 double2torus((*lv1_skey)[i] * (t + 1) * 7 pow(0.5, IKS_BASEBIT * (l + 1))), 8 ksk[i][l][t]); 9 } 10 } 11 }

上記の ksk へのアクセス方法に対して、以下の ksk の型定義は正しいでしょうか?

c

1kskey_t *ksk= malloc(sizeof(kskey_t));

どうもこちらがヒントになりそうな気がします。

c

1typedef struct TLWElv0 kskey_t[TRLWE_N][IKS_L][IKS_T];

投稿2021/09/07 07:47

mather

総合スコア6753

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hidekiti

2021/09/07 08:29

&(*ksk)[i][l][t]ですね! 型を4biteのu32ではなく8biteのポインタだと思ってコンパイラが走らせていたから、中途半端な添字でセグフォしていたということですね! 家に帰ったら試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問