# This circuit sums 2 256-bit values and (if needed) reduces the sum mod P-256 prime # ideally, we would need a proper circuit for 256-bit addition # since we only have a 64-bit circuit, we work around by summing chunks # (and waste ~500 AND gates in the process :( ) 24 1348 2 256 256 1 256 # the map of wires # 0|>512 inputs # 512: zero bit # 513: carry bit # 514|>257 sum of pms shares # 771|>64 temp storage for chunk additions # 835 "is less than" bit # 836|>256 prime's "one's complement" # 1092|>256 outputs 2 1 0 0 512 XOR #zero # add 1st batch of 63-bit summands 128 64 [0|>63] 512 [256|>63] 512 [514|>63] 513 adder64.txt # add the carry bit to one of the 2nd summands (pad the carry to 64 bits) 128 64 [63|>63] 512 513 [512*63] [771|>64] adder64.txt # add 2nd batch of summands 128 64 [771|>64] [319|>63] 512 [577|>63] 513 adder64.txt # carry bit + 3rd batch summand 128 64 [126|>63] 512 513 [512*63] [771|>64] adder64.txt # add 3rd batch of summands 128 64 [771|>64] [382|>63] 512 [640|>63] 513 adder64.txt # carry bit + 4th batch summand 128 64 [189|>63] 512 513 [512*63] [771|>64] adder64.txt # add 4th batch of summands 128 64 [771|>64] [445|>63] 512 [703|>63] 513 adder64.txt # one last batch of only 4 bits left #carry bit + 5th batch summand 128 64 [252|>4] [512*60] 513 [512*63] [771|>64] adder64.txt # add 5th batch of summands # only 5 bits of output go to the sum, the rest is discarded by assigning to some unused wires 128 64 [771|>64] [508|>4] [512*60] [766|>5] [836|>59] adder64.txt # --------------- 10 gates at this point # temporarily store the value in outputs section 2 256 0 1 [1092|>256] getP256prime.casm # check if prime is less than sum of shares # we only compare 32 msb (ideally we'd need a 256-bit comparing circuit) # we are comparing 256bits vs 257bits, so adding a 0 bit to prime's msb 64 1 [1317|>31] 512 [739|>32] 835 compare-lt-32-bit-unsigned-old.txt # temporarily store the value in outputs section 2 256 0 1 [1092|>256] getP256primeOnesComplement.casm # if sum of shares < prime, then we subtract 0, otherwise subtract prime 257 256 [1092|>256] 835 [836|>256] mult256by1.casm # we subtract using the "one's complement" method: # we add chunks of 63 bits like earlier to arrive at a 257-bit sum # (since we already know that minuend > subtrahend, the leading bit of the sum will always be one) # then drop the leading 1 of the sum and add 1 to the sum # add 1 from "one's complement" method to lsb of one of the batch1 summands # note that if sum of shares < prime, we add 0 instead of 1 128 64 [514|>63] 512 835 [512*63] [771|>64] adder64.txt # batch 1 add 128 64 [771|>64] [836|>63] 512 [1092|>63] 513 adder64.txt # add the carry bit to one of the 2nd summands (pad the carry to 64 bits) 128 64 [577|>63] 512 513 [512*63] [771|>64] adder64.txt # add the 2nd batch of summands 128 64 [771|>64] [899|>63] 512 [1155|>63] 513 adder64.txt # carry bit + 3rd batch summand 128 64 [640|>63] 512 513 [512*63] [771|>64] adder64.txt # add 3rd batch of summands 128 64 [771|>64] [962|>63] 512 [1218|>63] 513 adder64.txt # -------------------20 gates at this point # carry bit + 4th batch summand 128 64 [703|>63] 512 513 [512*63] [771|>64] adder64.txt # add 4th batch of summands 128 64 [771|>64] [1025|>63] 512 [1281|>63] 513 adder64.txt # one last batch of only 4 bits left # carry bit + 5th batch summand 128 64 [766|>5] [512*59] 513 [512*63] [771|>64] adder64.txt # add 5th batch of summands # only 4 bits of output go to the sum # (the 5th bit is discarded because of the "one's complement" method), # the rest is discarded by assigning it to some unused wires 128 64 [771|>64] [1088|>4] [512*60] [1344|>4] [836|>60] adder64.txt