ある秘密分散法のプログラムを作成していたところ,元の方で定義していた"p","q","N"(他にもあるかもしれません)の値をのちにもう一度使おうとしたら,おかしな値になってしまいました.理由がわかる方がいたらご教授いただきたいです.
定義した場所と利用した場所はコメントに示しています.
C(visual
1//逐次秘密分散法の実装 2#include <stdbool.h> 3#include<stdio.h> 4#include<math.h> 5 6int main(void){ 7 //繰り返し変数 8 int i,j,k; 9 10 //初期化フェーズ 11 12 //ディーラー 13 //レベル,閾値,プレイヤー数の決定 14 int m=3; 15 int t[m],n[m]; 16 t[1]=2,n[1]=2; 17 t[2]=2,n[2]=3; 18 t[3]=3,n[3]=4; 19 printf("m=%d\n",m); 20 for(i=1;i<=m;i++){ 21 printf("t[%d]=%d, n[%d]=%d\n",i,t[i],i,n[i]); 22 } 23 //素数P≡3mod4においてFPから各レベルのシークレットを選択する 24 int P=23; 25 int s[m]; 26 s[1]=3,s[2]=5,s[3]=5; 27 printf("P=%d\n",P); 28 for(i=1;i<=m;i++){ 29 printf("s[%d]=%d, ",i,s[i]); 30 } 31 printf("\n"); 32 //2つの安全な素数p,qを選択し,Nを公開する.ただしN<P 33 34 35 36 37 38**//ここでp,q,Nを定義した** 39 40 int p=7,q=3; 41 int N=p*q; 42 printf("p=%d, q=%d, N=%d\n",p,q,N); 43 //gをp,qに対して互いに素になるように[N^1/2,N]より整数を選択する 44 int g=5; 45 printf("g=%d\n",g); 46 // プレイヤー 47 //シークレットシャドウsijを[2,N]からランダムに選択し,Rijを計算する(sijをs1とする) 48 int s1[P][P],R[P][P]; 49 50 for(i=1;i<=m;i++){ 51 for(j=1;j<=n[i];j++){ 52 s1[i][j]=j; 53 printf("s[%d][%d]=%d, ",i,j,s1[i][j]); 54 } 55 printf("\n"); 56 } 57 for(i=1;i<=m;i++){ 58 for(j=1;j<=n[i];j++){ 59 R[i][j]=fmod(pow(g,s1[i][j]),N); 60 printf("R[%d][%d]=%d, ",i,j,R[i][j]); 61 } 62 printf("\n"); 63 } 64 //Rijが全てのレベルで一意であるか確認,一意でない場合sijを再選択 65 int count[m]; 66 printf("レベル"); 67 for(i=0;i<=m;i++)count[i]=0; 68 for(i=1;i<=m;i++){ 69 for(j=1;j<n[i];j++){ 70 for(k=j+1;k<=n[i];k++){ 71 if(R[i][j]==R[i][k])count[i]++; 72 } 73 } 74 if(count[i]==0)printf("%d,",i); 75 } 76 printf("で一意である.\n"); 77 78 //配布フェーズ 79 //ディーラー 80 //p-1,q-1に対して互いに素である素数s0を選択する 81 int s0=5; 82 printf("s0=%d\n",s0); 83 //s0*f=1modΦ(N)となるfを探す 84 for(i=1;i<P;i++){ 85 86 } 87 int f=17; 88 printf("Φ(N)=%d, f=%d\n",phi(N),f); 89 //R0を計算 90 int R0=fmod(pow(g,s0),N); 91 printf("R0=%d\n",R0); 92 93 94 int I[P][P]; 95 int S[m],K[m],ss[m]; 96 for(i=1;i<=m;i++){ 97 for(j=1;j<=n[i];j++){ 98 //Iijを計算する 99 I[i][j]=fmod(pow(R[i][j],s0),N); 100 printf("I[%d][%d]=%d, ",i,j,I[i][j]); 101 } 102 printf("\n"); 103 if(i==1){ 104 S[i]=s[i]; 105 106 } 107 else{ 108 K[i]=fmod(s[i]*ss[i-1],P); 109 printf("K[%d]=%d\n",i,K[i]); 110 //Kiが平方剰余か判断する 111 if(jacobi(K[i],P)==1){ 112 printf("K[%d]は平方剰余である\n",i); 113 S[i]=sqrt(K[i]); 114 printf("S[%d]=%d\n",i,S[i]); 115 } 116 else { 117 printf("K[%d]は平方剰余でない\n",i); 118 //Ki*RiがFPを方とする平方剰余となるようにFPから乱数Riを選択する(iをPまでにしているが,あっているか不明) 119 int R1[P];//R1はRi 120 for(k=2;k<P;k++){ 121 if(jacobi(K[i]*k,P)==1){ 122 R1[i]=k; 123 break; 124 } 125 } 126 printf("R[%d]=%d\n",i,R1[i]); 127 int r[m][P]; 128 for(j=1;j<=n[i];j++){ 129 r[i][j]=fmod(h(I[i][j],R1[i],t[i],P),P); 130 printf("r[%d][%d]=%d, ",i,j,r[i][j]); 131 } 132 printf("\n"); 133 S[i]=sqrt(fmod(K[i]*R1[i],P)); 134 } 135 } 136 //t1-1次関数hi(x)を作成 137 //yijを計算する 138 int y[m][P]; 139 for(j=1;j<=n[i];j++){ 140 y[i][j]=fmod(h(I[i][j],S[i],t[i],P),P); 141 printf("y[%d][%d]=%d, ",i,j,y[i][j]); 142 } 143 printf("\n"); 144 ss[i]=fmod(pow(g,S[i]),P);//ss=s' 145 if(i==m) printf("S[%d]=%d\n",i,S[i]); 146 else printf("S[%d]=%d, s'[%d]=%d\n",i,S[i],i,ss[i]); 147 } 148 149 //検証フェーズ 150 //プレイヤー 151 double I1[m][P];//I1=I' 152 int countv=0;//誤ったシェアのカウント 153 for(i=1;i<=m;i++){ 154 for(j=1;j<=n[i];j++){ 155 //I'ijを計算する 156 157 158 159 160 161 162 163 164 165**//ここで,p,q,Nの値がおかしくなる** 166 167 printf("R0=%d, s[%d][%d]=%d, N=%d\n",R0,s1[i][j],N); 168 I1[i][j]=pow1(R0,s1[i][j],N); 169 printf("I'[%d][%d]=%d,f=%d,N=%d\n",i,j,I1[i][j],f,N); 170 //Rij==I'ij^f mod Nを検証する 171 int h=pow1(I1[i][j],f,N); 172 printf("I'[%d][%d]^f mod N=%d\n",i,j,h); 173 printf(" R[%d][%d]=%d\n",i,j,R[i][j]); 174 if(R[i][j]!=h){ 175 printf("レベル%dの%d番目のプレイヤーは,誤ったシェアを提出しました\n",i,j); 176 countv++;//誤ったシェアがあればプラス1 177 } 178 } 179 } 180 if(countv==0)printf("全て正しいシェアでした\n"); 181 182 //復元フェーズ 183 //プレイヤー 184 double S1[m],r[m]; //求めるSi 185 double y1[m][P]; 186 for(i=1;i<=m;i++){ 187 S1[i]=0; 188 for(j=1;j<=t[i];j++){ 189 //ラグランジュ補間を使用して,Siを求める 190 y1[i][j]=fmod(h(I[i][j],S[i],t[i],P),P); 191 printf("y[%d][%d]=%lf, ",i,j,y1[i][j]); 192 r[i]=y1[i][j]; 193 for(k=1;k<=t[i];k++){ 194 if(j!=k){ 195 r[i]*=(0-I1[i][k])/(I1[i][j]-I1[i][k]); 196 197 } 198 } 199 200 S1[i]+=r[i]; 201 printf("S[%d]=%lf ",i,S1[i]); 202 S1[i]=fmod(S1[i],P); 203 204 } 205 S1[i]=round(S1[i]); 206 printf("S[%d]=%lf\n",i,S1[i]); 207 } 208 209 210 return 0; 211} 212 213 214 215 216 217 218//累乗計算 219int pow1(a,b,N){ 220 int p=1,i; 221 for(i=0;i<b;i++)p=fmod(p*a,N); 222 printf("pow1=%d\n",p); 223 return p; 224} 225 226//最大公約数を求める関数 227int gcd(a,b) 228{ 229 int temp; 230 while ( b > 0 ) { 231 temp = a % b, a = b; b = temp; 232 } 233 return a; 234} 235 236 237//ファイ関数 238int phi(n){ 239 int i, res=1; 240 for(i=2;i<n;i++){ 241 if(gcd(i,n)==1)res++; 242 } 243 return res; 244} 245 246//ti-1次関数を作成する関数(数値) 247int h(x,S,t,P){ 248 int ans=S; 249 int j,k; 250 int a[P],p[P]; 251 a[1]=1,a[2]=2,a[3]=3; 252 for(j=1;j<t;j++){ 253 p[j]=a[j]*pow(x,j); 254 ans +=p[j]; 255 } 256 return ans; 257} 258 259//平方剰余か判断 260int jacobi(a,p){ 261 262 int x = 1; 263 int tmp; 264 if (p <= 0) return 0; 265 if (p > 2 && (p & 1) == 0) return 0; 266 a %= p; 267 if (a < 0) a += p; 268 269 while (a > 1) { 270 if (a & 1) { 271 if ((a & 3) == 3 && (p & 3) == 3) x = -x; 272 tmp = p; 273 p = a; 274 a = tmp; 275 a = a % p; 276 } else { 277 a >>= 1; 278 if ((p & 7) == 3 || (p & 7) == 5) x = -x; 279 } 280 } 281 if (a == 0) return 1; 282 return x; 283} 284 285
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。