You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
2.8 KiB

  1. pragma circom 2.0.0;
  2. include "./utils.circom";
  3. include "./theta.circom";
  4. include "./rhopi.circom";
  5. include "./chi.circom";
  6. include "./iota.circom";
  7. template Pad(nBits) {
  8. signal input in[nBits];
  9. var blockSize=136*8;
  10. signal output out[blockSize];
  11. signal out2[blockSize];
  12. var i;
  13. for (i=0; i<nBits; i++) {
  14. out2[i] <== in[i];
  15. }
  16. var domain = 0x01;
  17. for (i=0; i<8; i++) {
  18. out2[nBits+i] <== (domain >> i) & 1;
  19. }
  20. for (i=nBits+8; i<blockSize; i++) {
  21. out2[i] <== 0;
  22. }
  23. component aux = OrArray(8);
  24. for (i=0; i<8; i++) {
  25. aux.a[i] <== out2[blockSize-8+i];
  26. aux.b[i] <== (0x80 >> i) & 1;
  27. }
  28. for (i=0; i<8; i++) {
  29. out[blockSize-8+i] <== aux.out[i];
  30. }
  31. for (i=0; i<blockSize-8; i++) {
  32. out[i]<==out2[i];
  33. }
  34. }
  35. template KeccakfRound(r) {
  36. signal input in[25*64];
  37. signal output out[25*64];
  38. var i;
  39. component theta = Theta();
  40. component rhopi = RhoPi();
  41. component chi = Chi();
  42. component iota = Iota(r);
  43. for (i=0; i<25*64; i++) {
  44. theta.in[i] <== in[i];
  45. }
  46. for (i=0; i<25*64; i++) {
  47. rhopi.in[i] <== theta.out[i];
  48. }
  49. for (i=0; i<25*64; i++) {
  50. chi.in[i] <== rhopi.out[i];
  51. }
  52. for (i=0; i<25*64; i++) {
  53. iota.in[i] <== chi.out[i];
  54. }
  55. for (i=0; i<25*64; i++) {
  56. out[i] <== iota.out[i];
  57. }
  58. }
  59. template Absorb() {
  60. var blockSizeBytes=136;
  61. signal input s[25*64];
  62. signal input block[blockSizeBytes*8];
  63. signal output out[25*64];
  64. var i;
  65. var j;
  66. component aux[blockSizeBytes/8];
  67. component newS = Keccakf();
  68. for (i=0; i<blockSizeBytes/8; i++) {
  69. aux[i] = XorArray(64);
  70. for (j=0; j<64; j++) {
  71. aux[i].a[j] <== s[i*64+j];
  72. aux[i].b[j] <== block[i*64+j];
  73. }
  74. for (j=0; j<64; j++) {
  75. newS.in[i*64+j] <== aux[i].out[j];
  76. }
  77. }
  78. // fill the missing s that was not covered by the loop over
  79. // blockSizeBytes/8
  80. for (i=(blockSizeBytes/8)*64; i<25*64; i++) {
  81. newS.in[i] <== s[i];
  82. }
  83. for (i=0; i<25*64; i++) {
  84. out[i] <== newS.out[i];
  85. }
  86. }
  87. template Keccakf() {
  88. signal input in[25*64];
  89. signal output out[25*64];
  90. var i;
  91. var j;
  92. // 24 rounds
  93. component round[24];
  94. signal midRound[24*25*64];
  95. for (i=0; i<24; i++) {
  96. round[i] = KeccakfRound(i);
  97. if (i==0) {
  98. for (j=0; j<25*64; j++) {
  99. midRound[j] <== in[j];
  100. }
  101. }
  102. for (j=0; j<25*64; j++) {
  103. round[i].in[j] <== midRound[i*25*64+j];
  104. }
  105. if (i<23) {
  106. for (j=0; j<25*64; j++) {
  107. midRound[(i+1)*25*64+j] <== round[i].out[j];
  108. }
  109. }
  110. }
  111. for (i=0; i<25*64; i++) {
  112. out[i] <== round[23].out[i];
  113. }
  114. }