環境
- 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}
回答1件
あなたの回答
tips
プレビュー