mirror of
https://github.com/logos-blockchain/logos-blockchain-pocs.git
synced 2026-01-07 15:43:07 +00:00
reflect changes in the specs to the circuits
This commit is contained in:
parent
2e20938880
commit
40e92abdb0
@ -1,224 +0,0 @@
|
||||
#!/usr/bin/sage
|
||||
# -*- mode: python ; -*-
|
||||
|
||||
|
||||
from sage.all import *
|
||||
|
||||
p = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
||||
F = FiniteField(p)
|
||||
|
||||
def poseidon2_hash(data):
|
||||
return PoseidonSponge(data,2,1)[0]
|
||||
|
||||
|
||||
|
||||
def Poseidon2_sponge_hash_rate_1(data, n):
|
||||
return PoseidonSponge(data,3,2,n,1)
|
||||
|
||||
def Poseidon2_sponge_hash_rate_2(data, n):
|
||||
return PoseidonSponge(data,3,1,n,1)
|
||||
|
||||
|
||||
def SBox(inp):
|
||||
return inp**5
|
||||
|
||||
def InternalRound(inp, i):
|
||||
round_consts = [ 0x15ce7e5ae220e8623a40b3a3b22d441eff0c9be1ae1d32f1b777af84eea7e38c
|
||||
, 0x1bf60ac8bfff0f631983c93e218ca0d4a4059c254b4299b1d9984a07edccfaf0
|
||||
, 0x0fab0c9387cb2bec9dc11b2951088b9e1e1d2978542fc131f74a8f8fdac95b40
|
||||
, 0x07d085a48750738019784663bccd460656dc62c1b18964a0d27a5bd0c27ee453
|
||||
, 0x10d57b1fad99da9d3fe16cf7f5dae05be844f67b2e7db3472a2e96e167578bc4
|
||||
, 0x0c36c40f7bd1934b7d5525031467aa39aeaea461996a70eda5a2a704e1733bb0
|
||||
, 0x0e4b65a0f3e1f9d3166a2145063c999bd08a4679676d765f4d11f97ed5c080ae
|
||||
, 0x1ce5561061120d5c7ea09da2528c4c041b9ad0f05d655f38b10d79878b69f29d
|
||||
, 0x2d323f651c3da8f0e0754391a10fa111b25dfa00471edf5493c44dfc3f28add6
|
||||
, 0x05a0741ee5bdc3e099fd6bdad9a0865bc9ceecd13ea4e702e536dd370b8f1953
|
||||
, 0x176a2ec4746fc0e0eca9e5e11d6facaee05524a92e5785c8b8161780a4435136
|
||||
, 0x0691faf0f42a9ed97629b1ae0dc7f1b019c06dd852cb6efe57f7eeb1aa865aef
|
||||
, 0x0e46cf138dad09d61b9a7cab95a23b5c8cb276874f3715598bacb55d5ad271de
|
||||
, 0x0f18c3d95bac1ac424160d240cdffc2c44f7b6315ba65ed3ff2eff5b3e48b4f2
|
||||
, 0x2eea6af14b592ec45a4119ac1e6e6f0312ecd090a096e340d472283e543ddff7
|
||||
, 0x06b0d7a8f4ce97d049ae994139f5f71dca4899d4f1cd3dd83a32a89a58c0a8e6
|
||||
, 0x019df0b9828eed5892dd55c1ad6408196f6293d600ef4491703a1b37e119ba8e
|
||||
, 0x08ca5e3c93817cdb1c2b2a12d02c779d74c1bb12b6668f3ab3ddd7837f3a4a00
|
||||
, 0x28382d747e3fd6cb2e0d8e8edd79c5313eed307a3517c11046245b1476e4f701
|
||||
, 0x0ca89aecd5675b77c8271765da98cfcb6875b3053d4742c9ff502861bd16ad28
|
||||
, 0x19046bc0b03ca90802ec83f212001e7ffd7f9224cfffae523451deb52eab3787
|
||||
, 0x036fd7dfa1c05110b3428e6abcc43e1de9abba915320c4a600f843bfb676ca51
|
||||
, 0x08f0a7abcb1a2f6595a9b7380c5028e3999db4fe5cb21892e5bb5cb11a7757ba
|
||||
, 0x0b614acc1ce3fbe9048f8385e4ee24c3843deea186bacea3c904c9f6340ad8cb
|
||||
, 0x00b2d98c5d988f9b41f2c98e017fc954a6ae423b2261575941f8eac8835d985c
|
||||
, 0x1457f18555b7973ba5b311d57ec5d77e936980b97f5973875f1f7cc765a4fc95
|
||||
, 0x002b453debc1bee525cb751bc10641a6b86f847d696418cf1144950982591bfa
|
||||
, 0x0c2af1abcc6ece77218315d2af445ccbfc6647b7af2510682882cc792c6bb8cf
|
||||
, 0x0e2825d9eb84b59902a1adb49ac0c2c291dee7c45d2e8c30369a4d595039e8ad
|
||||
, 0x297e2e86a8c672d39f3343b8dfce7a6f20f3571bfd5c8a28e3905aa2dcfeca44
|
||||
, 0x00d397281d902e49ec6504ba9186e806db9ad4fc8f86e7277aa7f1467eb6f9de
|
||||
, 0x2fb7c89c372d7e2050e7377ed471000c73544a2b9fd66557f3577c09cac98b4b
|
||||
, 0x16125247be4387a8c3e62490167f0cffdba02eda4f018d0b40639a13bb0cfef9
|
||||
, 0x2291fd9d442f2d9b97ab22f7d4d52c2a82e41f852cf620b144612650a39e26e8
|
||||
, 0x1eec61f16a275ae238540feaeeadfec56d32171b1cc393729d06f37f476fde71
|
||||
, 0x259ce871ba5dacbb48d8aed3d8513eef51558dc0b360f28c1a15dbfc5e7f6ca2
|
||||
, 0x2d3376a14ddbf95587e2f7567ff04fe13a3c7cb17363c8b9c5dd1d9262a210cb
|
||||
, 0x13b843d9f65f4cddd7ce10d9cad9b8b99ac5e9a8c4269288173a91c0f3c3b084
|
||||
, 0x0b52e9b2f1aa9fd204e4a42c481cc76c704783e34114b8e93e026a50fa9764e8
|
||||
, 0x1fd083229276c7f27d3ad941476b394ff37bd44d3a1e9caca1400d9077a2056c
|
||||
, 0x22743c328a6283f3ba7379af22c684c498568fd7ad9fad5151368c913197cbd9
|
||||
, 0x043007aefd9741070d95caaaba0c1b070e4eec8eef8c1e512c8e579c6ed64f76
|
||||
, 0x17ab175144f64bc843074f6b3a0c57c5dd2c954af8723c029ee642539496a7b3
|
||||
, 0x2befcad3d53fba5eeef8cae9668fed5c1e9e596a46e8458e218f7a665fddf4eb
|
||||
, 0x15151c4116d97de74bfa6ca3178f73c8fe8fe612c70c6f85a7a1551942cb71cc
|
||||
, 0x2ac40bf6c3176300a6835d5fc7cc4fd5e5d299fb1baa86487268ec1b9eedfa97
|
||||
, 0x0f151de1f01b4e24ffe04279318f0a68efabb485188f191e37e6915ff6059f6e
|
||||
, 0x2e43dffc34537535182aebac1ad7bf0a5533b88f65f9652f0ad584e2ffc4dd1f
|
||||
, 0x2ebabc2c37ef53d8b13b24a2a2b729d536735f58956125a3876da0664c2442d7
|
||||
, 0x0dc3beceb34e49f5ad7226dd202c5cf879dffcc9a6dd32a300e8f2a4b59edf03
|
||||
, 0x2f1ddeccce83adf68779c53b639871a8f81d4d00aefe1e812efce8ec999d457d
|
||||
, 0x1f63e41280ff5c021715d52b19780298ed8bd3d5eb506316b527e24149d4d4f1
|
||||
, 0x1b8c1252a5888f8cb2672effb5df49c633d3fd7183271488a1c40d0f88e7636e
|
||||
, 0x0f45697130f5498e2940568ef0d5e9e16b1095a6cdbb6411df20a973c605e70b
|
||||
, 0x0780ccc403cdd68983acbd34cda41cacfb2cf911a93076bc25587b4b0aed4929
|
||||
, 0x238d26ca97c691591e929f32199a643550f325f23a85d420080b289d7cecc9d4
|
||||
]
|
||||
|
||||
sb = SBox(inp[0] + round_consts[i])
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*sb + inp[1] + inp[2];
|
||||
out[1] = sb + 2*inp[1] + inp[2];
|
||||
out[2] = sb + inp[1] + 3*inp[2];
|
||||
return out
|
||||
|
||||
def ExternalRound(inp, i):
|
||||
out = [F(0) for j in range(3)]
|
||||
round_consts = [ [ F(0x2c4c51fd1bb9567c27e99f5712b49e0574178b41b6f0a476cddc41d242cf2b43)
|
||||
, F(0x1c5f8d18acb9c61ec6fcbfcda5356f1b3fdee7dc22c99a5b73a2750e5b054104)
|
||||
, F(0x2d3c1988b4541e4c045595b8d574e98a7c2820314a82e67a4e380f1c4541ba90 )
|
||||
]
|
||||
, [ F(0x052547dc9e6d936cab6680372f1734c39f490d0cb970e2077c82f7e4172943d3)
|
||||
, F(0x29d967f4002adcbb5a6037d644d36db91f591b088f69d9b4257694f5f9456bc2)
|
||||
, F(0x0350084b8305b91c426c25aeeecafc83fc5feec44b9636cb3b17d2121ec5b88a)
|
||||
]
|
||||
, [ F(0x1815d1e52a8196127530cc1e79f07a0ccd815fb5d94d070631f89f6c724d4cbe)
|
||||
, F(0x17b5ba882530af5d70466e2b434b0ccb15b7a8c0138d64455281e7724a066272)
|
||||
, F(0x1c859b60226b443767b73cd1b08823620de310bc49ea48662626014cea449aee)
|
||||
]
|
||||
, [ F(0x1b26e7f0ac7dd8b64c2f7a1904c958bb48d2635478a90d926f5ff2364effab37)
|
||||
, F(0x2da7f36850e6c377bdcdd380efd9e7c419555d3062b0997952dfbe5c54b1a22e)
|
||||
, F(0x17803c56450e74bc6c7ff97275390c017f682db11f3f4ca6e1f714efdfb9bd66)
|
||||
]
|
||||
, [ F(0x25672a14b5d085e31a30a7e1d5675ebfab034fb04dc2ec5e544887523f98dede)
|
||||
, F(0x0cf702434b891e1b2f1d71883506d68cdb1be36fa125674a3019647b3a98accd)
|
||||
, F(0x1837e75235ff5d112a5eddf7a4939448748339e7b5f2de683cf0c0ae98bdfbb3)
|
||||
]
|
||||
, [ F(0x1cd8a14cff3a61f04197a083c6485581a7d836941f6832704837a24b2d15613a)
|
||||
, F(0x266f6d85be0cef2ece525ba6a54b647ff789785069882772e6cac8131eecc1e4)
|
||||
, F(0x0538fde2183c3f5833ecd9e07edf30fe977d28dd6f246d7960889d9928b506b3)
|
||||
]
|
||||
, [ F(0x07a0693ff41476abb4664f3442596aa8399fdccf245d65882fce9a37c268aa04)
|
||||
, F(0x11eb49b07d33de2bd60ea68e7f652beda15644ed7855ee5a45763b576d216e8e)
|
||||
, F(0x08f8887da6ce51a8c06041f64e22697895f34bacb8c0a39ec12bf597f7c67cfc)
|
||||
]
|
||||
, [ F(0x2a912ec610191eb7662f86a52cc64c0122bd5ba762e1db8da79b5949fdd38092)
|
||||
, F(0x2031d7fd91b80857aa1fef64e23cfad9a9ba8fe8c8d09de92b1edb592a44c290)
|
||||
, F(0x0f81ebce43c47711751fa64d6c007221016d485641c28c507d04fd3dc7fba1d2)
|
||||
]
|
||||
]
|
||||
|
||||
sb = [F(0) for j in range(3)]
|
||||
for j in range(3):
|
||||
sb[j] = SBox(F(inp[j] + round_consts[i][j]))
|
||||
out = [F(0) for j in range(3)]
|
||||
out[0] = 2*sb[0] + sb[1] + sb[2]
|
||||
out[1] = sb[0] + 2*sb[1] + sb[2]
|
||||
out[2] = sb[0]+ sb[1] + 2*sb[2]
|
||||
return out
|
||||
|
||||
def LinearLayer(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*inp[0] + inp[1] + inp[2]
|
||||
out[1] = inp[0] + 2*inp[1] + inp[2]
|
||||
out[2] = inp[0] + inp[1] + 2*inp[2]
|
||||
return out
|
||||
|
||||
def Permutation(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
|
||||
state = LinearLayer(inp)
|
||||
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k)
|
||||
for k in range(56):
|
||||
state = InternalRound(state, k)
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k+4)
|
||||
return state
|
||||
|
||||
def Compression(inp):
|
||||
return Permutation([inp[0],inp[1],F(0)])
|
||||
|
||||
def PoseidonSponge(data, capacity, output_len):
|
||||
rate = 3 - capacity;
|
||||
output = [F(0) for i in range(output_len)]
|
||||
assert( capacity > 0 )
|
||||
assert( rate > 0 )
|
||||
assert( capacity < 3 )
|
||||
assert( rate < 3 )
|
||||
|
||||
# round up to rate the input + 1 field element ("10*" padding)
|
||||
nblocks = ((len(data) + 1) + (rate-1)) // rate;
|
||||
nout = (output_len + (rate-1)) // rate;
|
||||
padded_len = nblocks * rate;
|
||||
|
||||
padded = []
|
||||
for i in range(len(data)):
|
||||
padded.append(F(data[i]))
|
||||
padded.append(F(1))
|
||||
for i in range(len(data)+1,padded_len):
|
||||
padded.append(F(0))
|
||||
|
||||
civ = F(2**64 + 256*3 + rate)
|
||||
|
||||
state = [F(0),F(0),F(civ)]
|
||||
sorbed = [F(0) for j in range(rate)]
|
||||
|
||||
for m in range(nblocks):
|
||||
for i in range(rate):
|
||||
a = state[i]
|
||||
b = padded[m*rate+i]
|
||||
sorbed[i] = a + b
|
||||
state = Permutation(sorbed[0:rate] + state[rate:3])
|
||||
|
||||
q = min(rate, output_len)
|
||||
for i in range(q):
|
||||
output[i] = state[i]
|
||||
out_ptr = rate
|
||||
|
||||
for n in range(1,nout):
|
||||
state[nblocks+n] = Permutation(state[nblocks+n-1])
|
||||
q = min(rate, output_len-out_ptr)
|
||||
for i in range(q):
|
||||
output[out_ptr+i] = state[nblocks+n][i]
|
||||
out_ptr += rate
|
||||
|
||||
return output
|
||||
|
||||
R = RealField(500) #Real numbers with precision 500 bits
|
||||
|
||||
value = F(randrange(500,2**64-1,1))
|
||||
unit = F(161796427070100155131822184769584603407573991022311108406630770340454367555)
|
||||
state = F(randrange(0,p,1))
|
||||
zoneID = F(randrange(0,p,1))
|
||||
nonce = F(randrange(0,p,1))
|
||||
sk = F(randrange(0,p,1))
|
||||
|
||||
threshold = F(500)
|
||||
data_msg = F(randrange(0,p,1))
|
||||
|
||||
with open("input.json", "w") as file:
|
||||
file.write('{\n\t"state":\t\t\t\t\t\t"'+str(state)+'",')
|
||||
file.write('\n\t"value":\t\t\t\t\t\t"'+str(value)+'",')
|
||||
file.write('\n\t"nonce" :\t\t\t\t\t\t"'+str(nonce)+'",')
|
||||
file.write('\n\t"zoneID" :\t\t\t\t\t\t"'+str(zoneID)+'",')
|
||||
file.write('\n\t"secret_key" :\t\t\t\t\t\t"'+str(sk)+'",')
|
||||
file.write('\n\t"threshold" :\t\t\t\t\t\t"'+str(threshold)+'",')
|
||||
file.write('\n\t"attached_data" :\t\t\t\t\t\t"'+str(data_msg)+'"}')
|
||||
@ -202,21 +202,123 @@ def PoseidonSponge(data, capacity, output_len):
|
||||
|
||||
return output
|
||||
|
||||
R = RealField(500) #Real numbers with precision 500 bits
|
||||
if len(sys.argv) != Integer(3):
|
||||
print("Usage: <script> <private or public> <number of input>")
|
||||
exit()
|
||||
|
||||
value = F(randrange(0,2**64 - 1,1))
|
||||
unit = F(161796427070100155131822184769584603407573991022311108406630770340454367555)
|
||||
state = F(randrange(0,p,1))
|
||||
zoneID = F(randrange(0,p,1))
|
||||
nonce = F(randrange(0,p,1))
|
||||
sk = F(randrange(0,p,1))
|
||||
selector = str(sys.argv[Integer(1)])
|
||||
nInput = int(sys.argv[Integer(2)])
|
||||
|
||||
value = [F(randrange(0,2**64 - 1,1)) for i in range(nInput)]
|
||||
unit = F(19676183153323264216568033390884511718872104179761154996527087027500271872825)
|
||||
state = [F(randrange(0,p,1)) for i in range(nInput)]
|
||||
zoneID = [F(randrange(0,p,1)) for i in range(nInput)]
|
||||
nonce = [F(randrange(0,p,1)) for i in range(nInput)]
|
||||
sk = [F(randrange(0,p,1)) for i in range(nInput)]
|
||||
|
||||
data_msg = F(randrange(0,p,1))
|
||||
|
||||
with open("input.json", "w") as file:
|
||||
file.write('{\n\t"state":\t\t\t\t\t\t"'+str(state)+'",')
|
||||
file.write('\n\t"value":\t\t\t\t\t\t"'+str(value)+'",')
|
||||
file.write('\n\t"nonce" :\t\t\t\t\t\t"'+str(nonce)+'",')
|
||||
file.write('\n\t"zoneID" :\t\t\t\t\t\t"'+str(zoneID)+'",')
|
||||
file.write('\n\t"secret_key" :\t\t\t\t\t\t"'+str(sk)+'",')
|
||||
file.write('\n\t"attached_data" :\t\t\t\t\t\t"'+str(data_msg)+'"}')
|
||||
if selector == "private":
|
||||
if nInput == 1:
|
||||
with open("input.json", "w") as file:
|
||||
file.write('{\n\t"state":\t\t\t\t\t\t"'+str(state[0])+'",')
|
||||
file.write('\n\t"value":\t\t\t\t\t\t"'+str(value[0])+'",')
|
||||
file.write('\n\t"nonce" :\t\t\t\t\t\t"'+str(nonce[0])+'",')
|
||||
file.write('\n\t"zoneID" :\t\t\t\t\t\t"'+str(zoneID[0])+'",')
|
||||
file.write('\n\t"secret_key" :\t\t\t\t\t\t"'+str(sk[0])+'",')
|
||||
file.write('\n\t"minting_covenant" :\t\t\t\t\t\t"'+str(0)+'",')
|
||||
file.write('\n\t"transfer_covenant" :\t\t\t\t\t\t"'+str(0)+'",')
|
||||
file.write('\n\t"burning_covenant" :\t\t\t\t\t\t"'+str(0)+'",')
|
||||
file.write('\n\t"attached_data" :\t\t\t\t\t\t"'+str(data_msg)+'"}')
|
||||
else:
|
||||
with open("input.json", "w") as file:
|
||||
file.write('{\n\t"state" :\t\t\t\t\t[')
|
||||
for i in range(nInput):
|
||||
file.write('"')
|
||||
file.write(str(state[i]))
|
||||
file.write('"')
|
||||
if i == nInput - 1:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"value" :\t\t\t\t\t[')
|
||||
for i in range(nInput):
|
||||
file.write('"')
|
||||
file.write(str(value[i]))
|
||||
file.write('"')
|
||||
if i == nInput - 1:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"nonce" :\t\t\t\t\t[')
|
||||
for i in range(nInput):
|
||||
file.write('"')
|
||||
file.write(str(nonce[i]))
|
||||
file.write('"')
|
||||
if i == nInput - 1:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"zoneID" :\t\t\t\t\t[')
|
||||
for i in range(nInput):
|
||||
file.write('"')
|
||||
file.write(str(zoneID[i]))
|
||||
file.write('"')
|
||||
if i == nInput - 1:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"secret_key" :\t\t\t\t\t[')
|
||||
for i in range(nInput):
|
||||
file.write('"')
|
||||
file.write(str(sk[i]))
|
||||
file.write('"')
|
||||
if i == nInput - 1:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"minting_covenant" :\t\t\t\t\t[')
|
||||
for i in range(nInput):
|
||||
file.write('"')
|
||||
file.write(str(0))
|
||||
file.write('"')
|
||||
if i == nInput - 1:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"transfer_covenant" :\t\t\t\t\t[')
|
||||
for i in range(nInput):
|
||||
file.write('"')
|
||||
file.write(str(0))
|
||||
file.write('"')
|
||||
if i == nInput - 1:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"burning_covenant" :\t\t\t\t\t[')
|
||||
for i in range(nInput):
|
||||
file.write('"')
|
||||
file.write(str(0))
|
||||
file.write('"')
|
||||
if i == nInput - 1:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"attached_data" :\t\t\t\t\t\t"'+str(data_msg)+'"}')
|
||||
if selector == "public":
|
||||
if nInput == 1:
|
||||
with open("input.json", "w") as file:
|
||||
file.write('{\n\t"secret_key" :\t\t\t\t\t\t"'+str(sk[0])+'",')
|
||||
file.write('\n\t"attached_data" :\t\t\t\t\t\t"'+str(data_msg)+'"}')
|
||||
else:
|
||||
with open("input.json", "w") as file:
|
||||
file.write('{\n\t"secret_key" :\t\t\t\t\t[')
|
||||
for i in range(nInput):
|
||||
file.write('"')
|
||||
file.write(str(sk[i]))
|
||||
file.write('"')
|
||||
if i == nInput - 1:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"attached_data" :\t\t\t\t\t\t"'+str(data_msg)+'"}')
|
||||
@ -1,337 +0,0 @@
|
||||
#!/usr/bin/sage
|
||||
# -*- mode: python ; -*-
|
||||
|
||||
|
||||
from sage.all import *
|
||||
|
||||
p = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
||||
F = FiniteField(p)
|
||||
|
||||
def poseidon2_hash(data):
|
||||
return PoseidonSponge(data,2,1)[0]
|
||||
|
||||
|
||||
|
||||
def Poseidon2_sponge_hash_rate_1(data, n):
|
||||
return PoseidonSponge(data,3,2,n,1)
|
||||
|
||||
def Poseidon2_sponge_hash_rate_2(data, n):
|
||||
return PoseidonSponge(data,3,1,n,1)
|
||||
|
||||
|
||||
def SBox(inp):
|
||||
return inp**5
|
||||
|
||||
def InternalRound(inp, i):
|
||||
round_consts = [ 0x15ce7e5ae220e8623a40b3a3b22d441eff0c9be1ae1d32f1b777af84eea7e38c
|
||||
, 0x1bf60ac8bfff0f631983c93e218ca0d4a4059c254b4299b1d9984a07edccfaf0
|
||||
, 0x0fab0c9387cb2bec9dc11b2951088b9e1e1d2978542fc131f74a8f8fdac95b40
|
||||
, 0x07d085a48750738019784663bccd460656dc62c1b18964a0d27a5bd0c27ee453
|
||||
, 0x10d57b1fad99da9d3fe16cf7f5dae05be844f67b2e7db3472a2e96e167578bc4
|
||||
, 0x0c36c40f7bd1934b7d5525031467aa39aeaea461996a70eda5a2a704e1733bb0
|
||||
, 0x0e4b65a0f3e1f9d3166a2145063c999bd08a4679676d765f4d11f97ed5c080ae
|
||||
, 0x1ce5561061120d5c7ea09da2528c4c041b9ad0f05d655f38b10d79878b69f29d
|
||||
, 0x2d323f651c3da8f0e0754391a10fa111b25dfa00471edf5493c44dfc3f28add6
|
||||
, 0x05a0741ee5bdc3e099fd6bdad9a0865bc9ceecd13ea4e702e536dd370b8f1953
|
||||
, 0x176a2ec4746fc0e0eca9e5e11d6facaee05524a92e5785c8b8161780a4435136
|
||||
, 0x0691faf0f42a9ed97629b1ae0dc7f1b019c06dd852cb6efe57f7eeb1aa865aef
|
||||
, 0x0e46cf138dad09d61b9a7cab95a23b5c8cb276874f3715598bacb55d5ad271de
|
||||
, 0x0f18c3d95bac1ac424160d240cdffc2c44f7b6315ba65ed3ff2eff5b3e48b4f2
|
||||
, 0x2eea6af14b592ec45a4119ac1e6e6f0312ecd090a096e340d472283e543ddff7
|
||||
, 0x06b0d7a8f4ce97d049ae994139f5f71dca4899d4f1cd3dd83a32a89a58c0a8e6
|
||||
, 0x019df0b9828eed5892dd55c1ad6408196f6293d600ef4491703a1b37e119ba8e
|
||||
, 0x08ca5e3c93817cdb1c2b2a12d02c779d74c1bb12b6668f3ab3ddd7837f3a4a00
|
||||
, 0x28382d747e3fd6cb2e0d8e8edd79c5313eed307a3517c11046245b1476e4f701
|
||||
, 0x0ca89aecd5675b77c8271765da98cfcb6875b3053d4742c9ff502861bd16ad28
|
||||
, 0x19046bc0b03ca90802ec83f212001e7ffd7f9224cfffae523451deb52eab3787
|
||||
, 0x036fd7dfa1c05110b3428e6abcc43e1de9abba915320c4a600f843bfb676ca51
|
||||
, 0x08f0a7abcb1a2f6595a9b7380c5028e3999db4fe5cb21892e5bb5cb11a7757ba
|
||||
, 0x0b614acc1ce3fbe9048f8385e4ee24c3843deea186bacea3c904c9f6340ad8cb
|
||||
, 0x00b2d98c5d988f9b41f2c98e017fc954a6ae423b2261575941f8eac8835d985c
|
||||
, 0x1457f18555b7973ba5b311d57ec5d77e936980b97f5973875f1f7cc765a4fc95
|
||||
, 0x002b453debc1bee525cb751bc10641a6b86f847d696418cf1144950982591bfa
|
||||
, 0x0c2af1abcc6ece77218315d2af445ccbfc6647b7af2510682882cc792c6bb8cf
|
||||
, 0x0e2825d9eb84b59902a1adb49ac0c2c291dee7c45d2e8c30369a4d595039e8ad
|
||||
, 0x297e2e86a8c672d39f3343b8dfce7a6f20f3571bfd5c8a28e3905aa2dcfeca44
|
||||
, 0x00d397281d902e49ec6504ba9186e806db9ad4fc8f86e7277aa7f1467eb6f9de
|
||||
, 0x2fb7c89c372d7e2050e7377ed471000c73544a2b9fd66557f3577c09cac98b4b
|
||||
, 0x16125247be4387a8c3e62490167f0cffdba02eda4f018d0b40639a13bb0cfef9
|
||||
, 0x2291fd9d442f2d9b97ab22f7d4d52c2a82e41f852cf620b144612650a39e26e8
|
||||
, 0x1eec61f16a275ae238540feaeeadfec56d32171b1cc393729d06f37f476fde71
|
||||
, 0x259ce871ba5dacbb48d8aed3d8513eef51558dc0b360f28c1a15dbfc5e7f6ca2
|
||||
, 0x2d3376a14ddbf95587e2f7567ff04fe13a3c7cb17363c8b9c5dd1d9262a210cb
|
||||
, 0x13b843d9f65f4cddd7ce10d9cad9b8b99ac5e9a8c4269288173a91c0f3c3b084
|
||||
, 0x0b52e9b2f1aa9fd204e4a42c481cc76c704783e34114b8e93e026a50fa9764e8
|
||||
, 0x1fd083229276c7f27d3ad941476b394ff37bd44d3a1e9caca1400d9077a2056c
|
||||
, 0x22743c328a6283f3ba7379af22c684c498568fd7ad9fad5151368c913197cbd9
|
||||
, 0x043007aefd9741070d95caaaba0c1b070e4eec8eef8c1e512c8e579c6ed64f76
|
||||
, 0x17ab175144f64bc843074f6b3a0c57c5dd2c954af8723c029ee642539496a7b3
|
||||
, 0x2befcad3d53fba5eeef8cae9668fed5c1e9e596a46e8458e218f7a665fddf4eb
|
||||
, 0x15151c4116d97de74bfa6ca3178f73c8fe8fe612c70c6f85a7a1551942cb71cc
|
||||
, 0x2ac40bf6c3176300a6835d5fc7cc4fd5e5d299fb1baa86487268ec1b9eedfa97
|
||||
, 0x0f151de1f01b4e24ffe04279318f0a68efabb485188f191e37e6915ff6059f6e
|
||||
, 0x2e43dffc34537535182aebac1ad7bf0a5533b88f65f9652f0ad584e2ffc4dd1f
|
||||
, 0x2ebabc2c37ef53d8b13b24a2a2b729d536735f58956125a3876da0664c2442d7
|
||||
, 0x0dc3beceb34e49f5ad7226dd202c5cf879dffcc9a6dd32a300e8f2a4b59edf03
|
||||
, 0x2f1ddeccce83adf68779c53b639871a8f81d4d00aefe1e812efce8ec999d457d
|
||||
, 0x1f63e41280ff5c021715d52b19780298ed8bd3d5eb506316b527e24149d4d4f1
|
||||
, 0x1b8c1252a5888f8cb2672effb5df49c633d3fd7183271488a1c40d0f88e7636e
|
||||
, 0x0f45697130f5498e2940568ef0d5e9e16b1095a6cdbb6411df20a973c605e70b
|
||||
, 0x0780ccc403cdd68983acbd34cda41cacfb2cf911a93076bc25587b4b0aed4929
|
||||
, 0x238d26ca97c691591e929f32199a643550f325f23a85d420080b289d7cecc9d4
|
||||
]
|
||||
|
||||
sb = SBox(inp[0] + round_consts[i])
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*sb + inp[1] + inp[2];
|
||||
out[1] = sb + 2*inp[1] + inp[2];
|
||||
out[2] = sb + inp[1] + 3*inp[2];
|
||||
return out
|
||||
|
||||
def ExternalRound(inp, i):
|
||||
out = [F(0) for j in range(3)]
|
||||
round_consts = [ [ F(0x2c4c51fd1bb9567c27e99f5712b49e0574178b41b6f0a476cddc41d242cf2b43)
|
||||
, F(0x1c5f8d18acb9c61ec6fcbfcda5356f1b3fdee7dc22c99a5b73a2750e5b054104)
|
||||
, F(0x2d3c1988b4541e4c045595b8d574e98a7c2820314a82e67a4e380f1c4541ba90 )
|
||||
]
|
||||
, [ F(0x052547dc9e6d936cab6680372f1734c39f490d0cb970e2077c82f7e4172943d3)
|
||||
, F(0x29d967f4002adcbb5a6037d644d36db91f591b088f69d9b4257694f5f9456bc2)
|
||||
, F(0x0350084b8305b91c426c25aeeecafc83fc5feec44b9636cb3b17d2121ec5b88a)
|
||||
]
|
||||
, [ F(0x1815d1e52a8196127530cc1e79f07a0ccd815fb5d94d070631f89f6c724d4cbe)
|
||||
, F(0x17b5ba882530af5d70466e2b434b0ccb15b7a8c0138d64455281e7724a066272)
|
||||
, F(0x1c859b60226b443767b73cd1b08823620de310bc49ea48662626014cea449aee)
|
||||
]
|
||||
, [ F(0x1b26e7f0ac7dd8b64c2f7a1904c958bb48d2635478a90d926f5ff2364effab37)
|
||||
, F(0x2da7f36850e6c377bdcdd380efd9e7c419555d3062b0997952dfbe5c54b1a22e)
|
||||
, F(0x17803c56450e74bc6c7ff97275390c017f682db11f3f4ca6e1f714efdfb9bd66)
|
||||
]
|
||||
, [ F(0x25672a14b5d085e31a30a7e1d5675ebfab034fb04dc2ec5e544887523f98dede)
|
||||
, F(0x0cf702434b891e1b2f1d71883506d68cdb1be36fa125674a3019647b3a98accd)
|
||||
, F(0x1837e75235ff5d112a5eddf7a4939448748339e7b5f2de683cf0c0ae98bdfbb3)
|
||||
]
|
||||
, [ F(0x1cd8a14cff3a61f04197a083c6485581a7d836941f6832704837a24b2d15613a)
|
||||
, F(0x266f6d85be0cef2ece525ba6a54b647ff789785069882772e6cac8131eecc1e4)
|
||||
, F(0x0538fde2183c3f5833ecd9e07edf30fe977d28dd6f246d7960889d9928b506b3)
|
||||
]
|
||||
, [ F(0x07a0693ff41476abb4664f3442596aa8399fdccf245d65882fce9a37c268aa04)
|
||||
, F(0x11eb49b07d33de2bd60ea68e7f652beda15644ed7855ee5a45763b576d216e8e)
|
||||
, F(0x08f8887da6ce51a8c06041f64e22697895f34bacb8c0a39ec12bf597f7c67cfc)
|
||||
]
|
||||
, [ F(0x2a912ec610191eb7662f86a52cc64c0122bd5ba762e1db8da79b5949fdd38092)
|
||||
, F(0x2031d7fd91b80857aa1fef64e23cfad9a9ba8fe8c8d09de92b1edb592a44c290)
|
||||
, F(0x0f81ebce43c47711751fa64d6c007221016d485641c28c507d04fd3dc7fba1d2)
|
||||
]
|
||||
]
|
||||
|
||||
sb = [F(0) for j in range(3)]
|
||||
for j in range(3):
|
||||
sb[j] = SBox(F(inp[j] + round_consts[i][j]))
|
||||
out = [F(0) for j in range(3)]
|
||||
out[0] = 2*sb[0] + sb[1] + sb[2]
|
||||
out[1] = sb[0] + 2*sb[1] + sb[2]
|
||||
out[2] = sb[0]+ sb[1] + 2*sb[2]
|
||||
return out
|
||||
|
||||
def LinearLayer(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*inp[0] + inp[1] + inp[2]
|
||||
out[1] = inp[0] + 2*inp[1] + inp[2]
|
||||
out[2] = inp[0] + inp[1] + 2*inp[2]
|
||||
return out
|
||||
|
||||
def Permutation(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
|
||||
state = LinearLayer(inp)
|
||||
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k)
|
||||
for k in range(56):
|
||||
state = InternalRound(state, k)
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k+4)
|
||||
return state
|
||||
|
||||
def Compression(inp):
|
||||
return Permutation([inp[0],inp[1],F(0)])
|
||||
|
||||
def PoseidonSponge(data, capacity, output_len):
|
||||
rate = 3 - capacity;
|
||||
output = [F(0) for i in range(output_len)]
|
||||
assert( capacity > 0 )
|
||||
assert( rate > 0 )
|
||||
assert( capacity < 3 )
|
||||
assert( rate < 3 )
|
||||
|
||||
# round up to rate the input + 1 field element ("10*" padding)
|
||||
nblocks = ((len(data) + 1) + (rate-1)) // rate;
|
||||
nout = (output_len + (rate-1)) // rate;
|
||||
padded_len = nblocks * rate;
|
||||
|
||||
padded = []
|
||||
for i in range(len(data)):
|
||||
padded.append(F(data[i]))
|
||||
padded.append(F(1))
|
||||
for i in range(len(data)+1,padded_len):
|
||||
padded.append(F(0))
|
||||
|
||||
civ = F(2**64 + 256*3 + rate)
|
||||
|
||||
state = [F(0),F(0),F(civ)]
|
||||
sorbed = [F(0) for j in range(rate)]
|
||||
|
||||
for m in range(nblocks):
|
||||
for i in range(rate):
|
||||
a = state[i]
|
||||
b = padded[m*rate+i]
|
||||
sorbed[i] = a + b
|
||||
state = Permutation(sorbed[0:rate] + state[rate:3])
|
||||
|
||||
q = min(rate, output_len)
|
||||
for i in range(q):
|
||||
output[i] = state[i]
|
||||
out_ptr = rate
|
||||
|
||||
for n in range(1,nout):
|
||||
state[nblocks+n] = Permutation(state[nblocks+n-1])
|
||||
q = min(rate, output_len-out_ptr)
|
||||
for i in range(q):
|
||||
output[out_ptr+i] = state[nblocks+n][i]
|
||||
out_ptr += rate
|
||||
|
||||
return output
|
||||
|
||||
R = RealField(500) #Real numbers with precision 500 bits
|
||||
|
||||
if len(sys.argv) != Integer(4):
|
||||
print("Usage: <script> <epoch_nonce> <slot_number> <total_stake>")
|
||||
exit()
|
||||
|
||||
epoch_nonce = int(sys.argv[Integer(1)])
|
||||
slot_number = int(sys.argv[Integer(2)])
|
||||
total_stake = int(sys.argv[Integer(3)])
|
||||
|
||||
if epoch_nonce >= p:
|
||||
print("epoch nonce must be less than p")
|
||||
exit()
|
||||
if total_stake >= p:
|
||||
print("total stake must be less than p")
|
||||
exit()
|
||||
|
||||
t0 = F(int(-((R(p) * ln(R(1) - 0.05))) / R(total_stake)))
|
||||
t1 = F(int(-((R(p) * ln(R(1) - 0.05))**2) / R(total_stake)**2))
|
||||
|
||||
|
||||
value = F(50)
|
||||
unit = F(161796427070100155131822184769584603407573991022311108406630770340454367555)
|
||||
state = F(randrange(0,p,1))
|
||||
note_nonce = F(0)
|
||||
threshold = (t0 + t1 * value) * value
|
||||
starting_slot = randrange(max(0,slot_number-2**25+1),slot_number,1)
|
||||
|
||||
slot_secret = F(randrange(0,p,1))
|
||||
slot_secret_indexes = format(slot_number - starting_slot,'025b')
|
||||
|
||||
slot_secret_path = [F(randrange(0,p,1)) for i in range(25)]
|
||||
secret_root = slot_secret
|
||||
for i in range(25):
|
||||
if int(slot_secret_indexes[24-i]) == 0:
|
||||
secret_root = poseidon2_hash([secret_root,slot_secret_path[i]])
|
||||
else:
|
||||
secret_root = poseidon2_hash([slot_secret_path[i],secret_root])
|
||||
sk = poseidon2_hash([F(313763129738690320248895675268201668175331181115752393250540330459318963992),starting_slot,secret_root])
|
||||
pk = poseidon2_hash([F(355994159511987982411097843485998670968942801951585260613801918349630142543),sk])
|
||||
|
||||
note_cm = poseidon2_hash([F(181645510297841241569044198526601622686169271532834574969543446901055041748),state,value,unit,note_nonce,pk,F(281646683567839822174419720505039861445414630574005374635737888376398200354)])
|
||||
ticket = poseidon2_hash([F(137836078329650723736739065075984465408055658421620421917147974048265460598),F(epoch_nonce),F(slot_number),note_cm,sk])
|
||||
while(ticket > threshold):
|
||||
note_nonce += 1
|
||||
note_cm = poseidon2_hash([F(181645510297841241569044198526601622686169271532834574969543446901055041748),state,value,unit,note_nonce,pk,F(281646683567839822174419720505039861445414630574005374635737888376398200354)])
|
||||
ticket = poseidon2_hash([F(137836078329650723736739065075984465408055658421620421917147974048265460598),F(epoch_nonce),F(slot_number),note_cm,sk])
|
||||
|
||||
cm_nodes = [F(randrange(0,p,1)) for i in range(32)]
|
||||
cm_selectors = randrange(0,2**32,1)
|
||||
cm_selectors = format(cm_selectors,'032b')
|
||||
cm_root = note_cm
|
||||
for i in range(32):
|
||||
if int(cm_selectors[31-i]) == 0:
|
||||
cm_root = poseidon2_hash([cm_root,cm_nodes[i]])
|
||||
else:
|
||||
cm_root = poseidon2_hash([cm_nodes[i],cm_root])
|
||||
|
||||
note_nf = poseidon2_hash([F(310945536431723660304787929213143698356852257431717126117833288836338828411),note_cm,sk])
|
||||
nf_previous = F(randrange(0,note_nf,1))
|
||||
nf_next = F(randrange(note_nf+1,p,1))
|
||||
nf_nodes = [F(randrange(0,p,1)) for i in range(32)]
|
||||
nf_selectors = randrange(0,2**32,1)
|
||||
nf_selectors = format(nf_selectors,'032b')
|
||||
|
||||
nf_root = poseidon2_hash([nf_previous, nf_next])
|
||||
for i in range(32):
|
||||
if int(nf_selectors[31-i]) == 0:
|
||||
nf_root = poseidon2_hash([nf_root,nf_nodes[i]])
|
||||
else:
|
||||
nf_root = poseidon2_hash([nf_nodes[i],nf_root])
|
||||
|
||||
with open("input.json", "w") as file:
|
||||
file.write('{\n\t"slot":\t\t\t\t\t\t"'+str(slot_number)+'",')
|
||||
file.write('\n\t"epoch_nonce":\t\t\t\t\t\t"'+str(epoch_nonce)+'",')
|
||||
file.write('\n\t"t0" :\t\t\t\t\t\t"'+str(t0)+'",')
|
||||
file.write('\n\t"t1" :\t\t\t\t\t\t"'+str(t1)+'",')
|
||||
file.write('\n\t"slot_secret" :\t\t\t\t\t\t"'+str(slot_secret)+'",')
|
||||
file.write('\n\t"one_time_key" :\t\t\t\t\t\t"'+str(F(516548))+'",')
|
||||
file.write('\n\t"slot_secret_path" :\t\t\t\t\t[')
|
||||
for i in range(25):
|
||||
file.write('"')
|
||||
file.write(str(slot_secret_path[i]))
|
||||
file.write('"')
|
||||
if i == 24:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"cm_nodes" :\t\t\t\t\t[')
|
||||
for i in range(32):
|
||||
file.write('"')
|
||||
file.write(str(cm_nodes[i]))
|
||||
file.write('"')
|
||||
if i == 31:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"cm_selectors" :\t\t\t\t\t[')
|
||||
for i in range(32):
|
||||
file.write('"')
|
||||
file.write(str(cm_selectors[i]))
|
||||
file.write('"')
|
||||
if i == 31:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"commitments_root" :\t\t\t\t"'+str(cm_root)+'",')
|
||||
file.write('\n\t"nf_previous" :\t\t\t\t"'+str(nf_previous)+'",')
|
||||
file.write('\n\t"nf_next" :\t\t\t\t"'+str(nf_next)+'",')
|
||||
file.write('\n\t"nf_nodes" :\t\t\t\t\t[')
|
||||
for i in range(32):
|
||||
file.write('"')
|
||||
file.write(str(nf_nodes[i]))
|
||||
file.write('"')
|
||||
if i == 31:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"nf_selectors" :\t\t\t\t\t[')
|
||||
for i in range(32):
|
||||
file.write('"')
|
||||
file.write(str(nf_selectors[i]))
|
||||
file.write('"')
|
||||
if i == 31:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"nullifiers_root" :\t\t\t\t"'+str(nf_root)+'",')
|
||||
file.write('\n\t"starting_slot" :\t\t\t\t"'+str(starting_slot)+'",')
|
||||
file.write('\n\t"secrets_root" :\t\t\t\t"'+str(secret_root)+'",')
|
||||
file.write('\n\t"state" :\t\t\t\t"'+str(state)+'",')
|
||||
file.write('\n\t"value" :\t\t\t\t"'+str(value)+'",')
|
||||
file.write('\n\t"nonce" :\t\t\t\t"'+str(note_nonce)+'"}')
|
||||
@ -204,13 +204,14 @@ def PoseidonSponge(data, capacity, output_len):
|
||||
|
||||
R = RealField(500) #Real numbers with precision 500 bits
|
||||
|
||||
if len(sys.argv) != Integer(4):
|
||||
print("Usage: <script> <epoch_nonce> <slot_number> <total_stake>")
|
||||
if len(sys.argv) != Integer(5):
|
||||
print("Usage: <script> <epoch_nonce> <slot_number> <total_stake> <public or private>")
|
||||
exit()
|
||||
|
||||
epoch_nonce = int(sys.argv[Integer(1)])
|
||||
slot_number = int(sys.argv[Integer(2)])
|
||||
total_stake = int(sys.argv[Integer(3)])
|
||||
anonymity = str(sys.argv[Integer(4)])
|
||||
|
||||
if epoch_nonce >= p:
|
||||
print("epoch nonce must be less than p")
|
||||
@ -224,7 +225,7 @@ t1 = F(int(-((R(p) * ln(R(1) - 0.05))**2) / R(total_stake)**2))
|
||||
|
||||
|
||||
value = F(50)
|
||||
unit = F(161796427070100155131822184769584603407573991022311108406630770340454367555)
|
||||
unit = F(19676183153323264216568033390884511718872104179761154996527087027500271872825)
|
||||
state = F(randrange(0,p,1))
|
||||
note_nonce = F(0)
|
||||
threshold = (t0 + t1 * value) * value
|
||||
@ -269,9 +270,27 @@ for i in range(32):
|
||||
cm_unspent_root = poseidon2_hash([cm_unspent_root,cm_unspent_nodes[i]])
|
||||
else:
|
||||
cm_unspent_root = poseidon2_hash([cm_unspent_nodes[i],cm_unspent_root])
|
||||
|
||||
note_nf = poseidon2_hash([F(310945536431723660304787929213143698356852257431717126117833288836338828411),note_cm,sk])
|
||||
nf_previous = F(randrange(0,note_nf,1))
|
||||
nf_next = F(randrange(note_nf+1,p,1))
|
||||
nf_nodes = [F(randrange(0,p,1)) for i in range(32)]
|
||||
nf_selectors = randrange(0,2**32,1)
|
||||
nf_selectors = format(nf_selectors,'032b')
|
||||
|
||||
nf_root = poseidon2_hash([nf_previous, nf_next])
|
||||
for i in range(32):
|
||||
if int(nf_selectors[31-i]) == 0:
|
||||
nf_root = poseidon2_hash([nf_root,nf_nodes[i]])
|
||||
else:
|
||||
nf_root = poseidon2_hash([nf_nodes[i],nf_root])
|
||||
|
||||
with open("input.json", "w") as file:
|
||||
file.write('{\n\t"slot":\t\t\t\t\t\t"'+str(slot_number)+'",')
|
||||
if anonymity == "public":
|
||||
file.write('\n\t"selector":\t\t\t\t\t\t"'+str(1)+'",')
|
||||
if anonymity == "private":
|
||||
file.write('\n\t"selector":\t\t\t\t\t\t"'+str(0)+'",')
|
||||
file.write('\n\t"epoch_nonce":\t\t\t\t\t\t"'+str(epoch_nonce)+'",')
|
||||
file.write('\n\t"t0" :\t\t\t\t\t\t"'+str(t0)+'",')
|
||||
file.write('\n\t"t1" :\t\t\t\t\t\t"'+str(t1)+'",')
|
||||
@ -305,25 +324,48 @@ with open("input.json", "w") as file:
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"commitments_aged_root" :\t\t\t\t"'+str(cm_aged_root)+'",')
|
||||
file.write('\n\t"cm_unspent_nodes" :\t\t\t\t\t[')
|
||||
for i in range(32):
|
||||
file.write('"')
|
||||
file.write(str(cm_unspent_nodes[i]))
|
||||
file.write('"')
|
||||
if i == 31:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"cm_unspent_selectors" :\t\t\t\t\t[')
|
||||
for i in range(32):
|
||||
file.write('"')
|
||||
file.write(str(cm_unspent_selectors[i]))
|
||||
file.write('"')
|
||||
if i == 31:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"commitments_unspent_root" :\t\t\t\t"'+str(cm_unspent_root)+'",')
|
||||
file.write('\n\t"nf_previous" :\t\t\t\t"'+str(nf_previous)+'",')
|
||||
file.write('\n\t"nf_next" :\t\t\t\t"'+str(nf_next)+'",')
|
||||
if anonymity == "public":
|
||||
file.write('\n\t"unspent_nodes" :\t\t\t\t\t[')
|
||||
for i in range(32):
|
||||
file.write('"')
|
||||
file.write(str(cm_unspent_nodes[i]))
|
||||
file.write('"')
|
||||
if i == 31:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"unspent_selectors" :\t\t\t\t\t[')
|
||||
for i in range(32):
|
||||
file.write('"')
|
||||
file.write(str(cm_unspent_selectors[i]))
|
||||
file.write('"')
|
||||
if i == 31:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"unspent_root" :\t\t\t\t"'+str(cm_unspent_root)+'",')
|
||||
if anonymity == "private":
|
||||
file.write('\n\t"unspent_nodes" :\t\t\t\t\t[')
|
||||
for i in range(32):
|
||||
file.write('"')
|
||||
file.write(str(nf_nodes[i]))
|
||||
file.write('"')
|
||||
if i == 31:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"unspent_selectors" :\t\t\t\t\t[')
|
||||
for i in range(32):
|
||||
file.write('"')
|
||||
file.write(str(nf_selectors[i]))
|
||||
file.write('"')
|
||||
if i == 31:
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"unspent_root" :\t\t\t\t"'+str(nf_root)+'",')
|
||||
file.write('\n\t"starting_slot" :\t\t\t\t"'+str(starting_slot)+'",')
|
||||
file.write('\n\t"secrets_root" :\t\t\t\t"'+str(secret_root)+'",')
|
||||
file.write('\n\t"state" :\t\t\t\t"'+str(state)+'",')
|
||||
@ -1,223 +0,0 @@
|
||||
#!/usr/bin/sage
|
||||
# -*- mode: python ; -*-
|
||||
|
||||
|
||||
from sage.all import *
|
||||
|
||||
p = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
||||
F = FiniteField(p)
|
||||
|
||||
def poseidon2_hash(data):
|
||||
return PoseidonSponge(data,2,1)[0]
|
||||
|
||||
|
||||
|
||||
def Poseidon2_sponge_hash_rate_1(data, n):
|
||||
return PoseidonSponge(data,3,2,n,1)
|
||||
|
||||
def Poseidon2_sponge_hash_rate_2(data, n):
|
||||
return PoseidonSponge(data,3,1,n,1)
|
||||
|
||||
|
||||
def SBox(inp):
|
||||
return inp**5
|
||||
|
||||
def InternalRound(inp, i):
|
||||
round_consts = [ 0x15ce7e5ae220e8623a40b3a3b22d441eff0c9be1ae1d32f1b777af84eea7e38c
|
||||
, 0x1bf60ac8bfff0f631983c93e218ca0d4a4059c254b4299b1d9984a07edccfaf0
|
||||
, 0x0fab0c9387cb2bec9dc11b2951088b9e1e1d2978542fc131f74a8f8fdac95b40
|
||||
, 0x07d085a48750738019784663bccd460656dc62c1b18964a0d27a5bd0c27ee453
|
||||
, 0x10d57b1fad99da9d3fe16cf7f5dae05be844f67b2e7db3472a2e96e167578bc4
|
||||
, 0x0c36c40f7bd1934b7d5525031467aa39aeaea461996a70eda5a2a704e1733bb0
|
||||
, 0x0e4b65a0f3e1f9d3166a2145063c999bd08a4679676d765f4d11f97ed5c080ae
|
||||
, 0x1ce5561061120d5c7ea09da2528c4c041b9ad0f05d655f38b10d79878b69f29d
|
||||
, 0x2d323f651c3da8f0e0754391a10fa111b25dfa00471edf5493c44dfc3f28add6
|
||||
, 0x05a0741ee5bdc3e099fd6bdad9a0865bc9ceecd13ea4e702e536dd370b8f1953
|
||||
, 0x176a2ec4746fc0e0eca9e5e11d6facaee05524a92e5785c8b8161780a4435136
|
||||
, 0x0691faf0f42a9ed97629b1ae0dc7f1b019c06dd852cb6efe57f7eeb1aa865aef
|
||||
, 0x0e46cf138dad09d61b9a7cab95a23b5c8cb276874f3715598bacb55d5ad271de
|
||||
, 0x0f18c3d95bac1ac424160d240cdffc2c44f7b6315ba65ed3ff2eff5b3e48b4f2
|
||||
, 0x2eea6af14b592ec45a4119ac1e6e6f0312ecd090a096e340d472283e543ddff7
|
||||
, 0x06b0d7a8f4ce97d049ae994139f5f71dca4899d4f1cd3dd83a32a89a58c0a8e6
|
||||
, 0x019df0b9828eed5892dd55c1ad6408196f6293d600ef4491703a1b37e119ba8e
|
||||
, 0x08ca5e3c93817cdb1c2b2a12d02c779d74c1bb12b6668f3ab3ddd7837f3a4a00
|
||||
, 0x28382d747e3fd6cb2e0d8e8edd79c5313eed307a3517c11046245b1476e4f701
|
||||
, 0x0ca89aecd5675b77c8271765da98cfcb6875b3053d4742c9ff502861bd16ad28
|
||||
, 0x19046bc0b03ca90802ec83f212001e7ffd7f9224cfffae523451deb52eab3787
|
||||
, 0x036fd7dfa1c05110b3428e6abcc43e1de9abba915320c4a600f843bfb676ca51
|
||||
, 0x08f0a7abcb1a2f6595a9b7380c5028e3999db4fe5cb21892e5bb5cb11a7757ba
|
||||
, 0x0b614acc1ce3fbe9048f8385e4ee24c3843deea186bacea3c904c9f6340ad8cb
|
||||
, 0x00b2d98c5d988f9b41f2c98e017fc954a6ae423b2261575941f8eac8835d985c
|
||||
, 0x1457f18555b7973ba5b311d57ec5d77e936980b97f5973875f1f7cc765a4fc95
|
||||
, 0x002b453debc1bee525cb751bc10641a6b86f847d696418cf1144950982591bfa
|
||||
, 0x0c2af1abcc6ece77218315d2af445ccbfc6647b7af2510682882cc792c6bb8cf
|
||||
, 0x0e2825d9eb84b59902a1adb49ac0c2c291dee7c45d2e8c30369a4d595039e8ad
|
||||
, 0x297e2e86a8c672d39f3343b8dfce7a6f20f3571bfd5c8a28e3905aa2dcfeca44
|
||||
, 0x00d397281d902e49ec6504ba9186e806db9ad4fc8f86e7277aa7f1467eb6f9de
|
||||
, 0x2fb7c89c372d7e2050e7377ed471000c73544a2b9fd66557f3577c09cac98b4b
|
||||
, 0x16125247be4387a8c3e62490167f0cffdba02eda4f018d0b40639a13bb0cfef9
|
||||
, 0x2291fd9d442f2d9b97ab22f7d4d52c2a82e41f852cf620b144612650a39e26e8
|
||||
, 0x1eec61f16a275ae238540feaeeadfec56d32171b1cc393729d06f37f476fde71
|
||||
, 0x259ce871ba5dacbb48d8aed3d8513eef51558dc0b360f28c1a15dbfc5e7f6ca2
|
||||
, 0x2d3376a14ddbf95587e2f7567ff04fe13a3c7cb17363c8b9c5dd1d9262a210cb
|
||||
, 0x13b843d9f65f4cddd7ce10d9cad9b8b99ac5e9a8c4269288173a91c0f3c3b084
|
||||
, 0x0b52e9b2f1aa9fd204e4a42c481cc76c704783e34114b8e93e026a50fa9764e8
|
||||
, 0x1fd083229276c7f27d3ad941476b394ff37bd44d3a1e9caca1400d9077a2056c
|
||||
, 0x22743c328a6283f3ba7379af22c684c498568fd7ad9fad5151368c913197cbd9
|
||||
, 0x043007aefd9741070d95caaaba0c1b070e4eec8eef8c1e512c8e579c6ed64f76
|
||||
, 0x17ab175144f64bc843074f6b3a0c57c5dd2c954af8723c029ee642539496a7b3
|
||||
, 0x2befcad3d53fba5eeef8cae9668fed5c1e9e596a46e8458e218f7a665fddf4eb
|
||||
, 0x15151c4116d97de74bfa6ca3178f73c8fe8fe612c70c6f85a7a1551942cb71cc
|
||||
, 0x2ac40bf6c3176300a6835d5fc7cc4fd5e5d299fb1baa86487268ec1b9eedfa97
|
||||
, 0x0f151de1f01b4e24ffe04279318f0a68efabb485188f191e37e6915ff6059f6e
|
||||
, 0x2e43dffc34537535182aebac1ad7bf0a5533b88f65f9652f0ad584e2ffc4dd1f
|
||||
, 0x2ebabc2c37ef53d8b13b24a2a2b729d536735f58956125a3876da0664c2442d7
|
||||
, 0x0dc3beceb34e49f5ad7226dd202c5cf879dffcc9a6dd32a300e8f2a4b59edf03
|
||||
, 0x2f1ddeccce83adf68779c53b639871a8f81d4d00aefe1e812efce8ec999d457d
|
||||
, 0x1f63e41280ff5c021715d52b19780298ed8bd3d5eb506316b527e24149d4d4f1
|
||||
, 0x1b8c1252a5888f8cb2672effb5df49c633d3fd7183271488a1c40d0f88e7636e
|
||||
, 0x0f45697130f5498e2940568ef0d5e9e16b1095a6cdbb6411df20a973c605e70b
|
||||
, 0x0780ccc403cdd68983acbd34cda41cacfb2cf911a93076bc25587b4b0aed4929
|
||||
, 0x238d26ca97c691591e929f32199a643550f325f23a85d420080b289d7cecc9d4
|
||||
]
|
||||
|
||||
sb = SBox(inp[0] + round_consts[i])
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*sb + inp[1] + inp[2];
|
||||
out[1] = sb + 2*inp[1] + inp[2];
|
||||
out[2] = sb + inp[1] + 3*inp[2];
|
||||
return out
|
||||
|
||||
def ExternalRound(inp, i):
|
||||
out = [F(0) for j in range(3)]
|
||||
round_consts = [ [ F(0x2c4c51fd1bb9567c27e99f5712b49e0574178b41b6f0a476cddc41d242cf2b43)
|
||||
, F(0x1c5f8d18acb9c61ec6fcbfcda5356f1b3fdee7dc22c99a5b73a2750e5b054104)
|
||||
, F(0x2d3c1988b4541e4c045595b8d574e98a7c2820314a82e67a4e380f1c4541ba90 )
|
||||
]
|
||||
, [ F(0x052547dc9e6d936cab6680372f1734c39f490d0cb970e2077c82f7e4172943d3)
|
||||
, F(0x29d967f4002adcbb5a6037d644d36db91f591b088f69d9b4257694f5f9456bc2)
|
||||
, F(0x0350084b8305b91c426c25aeeecafc83fc5feec44b9636cb3b17d2121ec5b88a)
|
||||
]
|
||||
, [ F(0x1815d1e52a8196127530cc1e79f07a0ccd815fb5d94d070631f89f6c724d4cbe)
|
||||
, F(0x17b5ba882530af5d70466e2b434b0ccb15b7a8c0138d64455281e7724a066272)
|
||||
, F(0x1c859b60226b443767b73cd1b08823620de310bc49ea48662626014cea449aee)
|
||||
]
|
||||
, [ F(0x1b26e7f0ac7dd8b64c2f7a1904c958bb48d2635478a90d926f5ff2364effab37)
|
||||
, F(0x2da7f36850e6c377bdcdd380efd9e7c419555d3062b0997952dfbe5c54b1a22e)
|
||||
, F(0x17803c56450e74bc6c7ff97275390c017f682db11f3f4ca6e1f714efdfb9bd66)
|
||||
]
|
||||
, [ F(0x25672a14b5d085e31a30a7e1d5675ebfab034fb04dc2ec5e544887523f98dede)
|
||||
, F(0x0cf702434b891e1b2f1d71883506d68cdb1be36fa125674a3019647b3a98accd)
|
||||
, F(0x1837e75235ff5d112a5eddf7a4939448748339e7b5f2de683cf0c0ae98bdfbb3)
|
||||
]
|
||||
, [ F(0x1cd8a14cff3a61f04197a083c6485581a7d836941f6832704837a24b2d15613a)
|
||||
, F(0x266f6d85be0cef2ece525ba6a54b647ff789785069882772e6cac8131eecc1e4)
|
||||
, F(0x0538fde2183c3f5833ecd9e07edf30fe977d28dd6f246d7960889d9928b506b3)
|
||||
]
|
||||
, [ F(0x07a0693ff41476abb4664f3442596aa8399fdccf245d65882fce9a37c268aa04)
|
||||
, F(0x11eb49b07d33de2bd60ea68e7f652beda15644ed7855ee5a45763b576d216e8e)
|
||||
, F(0x08f8887da6ce51a8c06041f64e22697895f34bacb8c0a39ec12bf597f7c67cfc)
|
||||
]
|
||||
, [ F(0x2a912ec610191eb7662f86a52cc64c0122bd5ba762e1db8da79b5949fdd38092)
|
||||
, F(0x2031d7fd91b80857aa1fef64e23cfad9a9ba8fe8c8d09de92b1edb592a44c290)
|
||||
, F(0x0f81ebce43c47711751fa64d6c007221016d485641c28c507d04fd3dc7fba1d2)
|
||||
]
|
||||
]
|
||||
|
||||
sb = [F(0) for j in range(3)]
|
||||
for j in range(3):
|
||||
sb[j] = SBox(F(inp[j] + round_consts[i][j]))
|
||||
out = [F(0) for j in range(3)]
|
||||
out[0] = 2*sb[0] + sb[1] + sb[2]
|
||||
out[1] = sb[0] + 2*sb[1] + sb[2]
|
||||
out[2] = sb[0]+ sb[1] + 2*sb[2]
|
||||
return out
|
||||
|
||||
def LinearLayer(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*inp[0] + inp[1] + inp[2]
|
||||
out[1] = inp[0] + 2*inp[1] + inp[2]
|
||||
out[2] = inp[0] + inp[1] + 2*inp[2]
|
||||
return out
|
||||
|
||||
def Permutation(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
|
||||
state = LinearLayer(inp)
|
||||
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k)
|
||||
for k in range(56):
|
||||
state = InternalRound(state, k)
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k+4)
|
||||
return state
|
||||
|
||||
def Compression(inp):
|
||||
return Permutation([inp[0],inp[1],F(0)])
|
||||
|
||||
def PoseidonSponge(data, capacity, output_len):
|
||||
rate = 3 - capacity;
|
||||
output = [F(0) for i in range(output_len)]
|
||||
assert( capacity > 0 )
|
||||
assert( rate > 0 )
|
||||
assert( capacity < 3 )
|
||||
assert( rate < 3 )
|
||||
|
||||
# round up to rate the input + 1 field element ("10*" padding)
|
||||
nblocks = ((len(data) + 1) + (rate-1)) // rate;
|
||||
nout = (output_len + (rate-1)) // rate;
|
||||
padded_len = nblocks * rate;
|
||||
|
||||
padded = []
|
||||
for i in range(len(data)):
|
||||
padded.append(F(data[i]))
|
||||
padded.append(F(1))
|
||||
for i in range(len(data)+1,padded_len):
|
||||
padded.append(F(0))
|
||||
|
||||
civ = F(2**64 + 256*3 + rate)
|
||||
|
||||
state = [F(0),F(0),F(civ)]
|
||||
sorbed = [F(0) for j in range(rate)]
|
||||
|
||||
for m in range(nblocks):
|
||||
for i in range(rate):
|
||||
a = state[i]
|
||||
b = padded[m*rate+i]
|
||||
sorbed[i] = a + b
|
||||
state = Permutation(sorbed[0:rate] + state[rate:3])
|
||||
|
||||
q = min(rate, output_len)
|
||||
for i in range(q):
|
||||
output[i] = state[i]
|
||||
out_ptr = rate
|
||||
|
||||
for n in range(1,nout):
|
||||
state[nblocks+n] = Permutation(state[nblocks+n-1])
|
||||
q = min(rate, output_len-out_ptr)
|
||||
for i in range(q):
|
||||
output[out_ptr+i] = state[nblocks+n][i]
|
||||
out_ptr += rate
|
||||
|
||||
return output
|
||||
|
||||
R = RealField(500) #Real numbers with precision 500 bits
|
||||
|
||||
value = F(randrange(0,2**64 - 1,1))
|
||||
unit = F(161796427070100155131822184769584603407573991022311108406630770340454367555)
|
||||
state = F(randrange(0,p,1))
|
||||
zoneID = F(randrange(0,p,1))
|
||||
nonce = F(randrange(0,p,1))
|
||||
previous_sk = F(randrange(0,p,1))
|
||||
new_sk = F(randrange(0,p,1))
|
||||
|
||||
data_msg = F(randrange(0,p,1))
|
||||
|
||||
with open("input.json", "w") as file:
|
||||
file.write('{\n\t"state":\t\t\t\t\t\t"'+str(state)+'",')
|
||||
file.write('\n\t"value":\t\t\t\t\t\t"'+str(value)+'",')
|
||||
file.write('\n\t"nonce" :\t\t\t\t\t\t"'+str(nonce)+'",')
|
||||
file.write('\n\t"previous_sk" :\t\t\t\t\t\t"'+str(previous_sk)+'",')
|
||||
file.write('\n\t"new_sk" :\t\t\t\t\t\t"'+str(new_sk)+'",')
|
||||
file.write('\n\t"zoneID" :\t\t\t\t\t\t"'+str(zoneID)+'"}')
|
||||
@ -1,219 +0,0 @@
|
||||
#!/usr/bin/sage
|
||||
# -*- mode: python ; -*-
|
||||
|
||||
|
||||
from sage.all import *
|
||||
|
||||
p = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
||||
F = FiniteField(p)
|
||||
|
||||
def poseidon2_hash(data):
|
||||
return PoseidonSponge(data,2,1)[0]
|
||||
|
||||
|
||||
|
||||
def Poseidon2_sponge_hash_rate_1(data, n):
|
||||
return PoseidonSponge(data,3,2,n,1)
|
||||
|
||||
def Poseidon2_sponge_hash_rate_2(data, n):
|
||||
return PoseidonSponge(data,3,1,n,1)
|
||||
|
||||
|
||||
def SBox(inp):
|
||||
return inp**5
|
||||
|
||||
def InternalRound(inp, i):
|
||||
round_consts = [ 0x15ce7e5ae220e8623a40b3a3b22d441eff0c9be1ae1d32f1b777af84eea7e38c
|
||||
, 0x1bf60ac8bfff0f631983c93e218ca0d4a4059c254b4299b1d9984a07edccfaf0
|
||||
, 0x0fab0c9387cb2bec9dc11b2951088b9e1e1d2978542fc131f74a8f8fdac95b40
|
||||
, 0x07d085a48750738019784663bccd460656dc62c1b18964a0d27a5bd0c27ee453
|
||||
, 0x10d57b1fad99da9d3fe16cf7f5dae05be844f67b2e7db3472a2e96e167578bc4
|
||||
, 0x0c36c40f7bd1934b7d5525031467aa39aeaea461996a70eda5a2a704e1733bb0
|
||||
, 0x0e4b65a0f3e1f9d3166a2145063c999bd08a4679676d765f4d11f97ed5c080ae
|
||||
, 0x1ce5561061120d5c7ea09da2528c4c041b9ad0f05d655f38b10d79878b69f29d
|
||||
, 0x2d323f651c3da8f0e0754391a10fa111b25dfa00471edf5493c44dfc3f28add6
|
||||
, 0x05a0741ee5bdc3e099fd6bdad9a0865bc9ceecd13ea4e702e536dd370b8f1953
|
||||
, 0x176a2ec4746fc0e0eca9e5e11d6facaee05524a92e5785c8b8161780a4435136
|
||||
, 0x0691faf0f42a9ed97629b1ae0dc7f1b019c06dd852cb6efe57f7eeb1aa865aef
|
||||
, 0x0e46cf138dad09d61b9a7cab95a23b5c8cb276874f3715598bacb55d5ad271de
|
||||
, 0x0f18c3d95bac1ac424160d240cdffc2c44f7b6315ba65ed3ff2eff5b3e48b4f2
|
||||
, 0x2eea6af14b592ec45a4119ac1e6e6f0312ecd090a096e340d472283e543ddff7
|
||||
, 0x06b0d7a8f4ce97d049ae994139f5f71dca4899d4f1cd3dd83a32a89a58c0a8e6
|
||||
, 0x019df0b9828eed5892dd55c1ad6408196f6293d600ef4491703a1b37e119ba8e
|
||||
, 0x08ca5e3c93817cdb1c2b2a12d02c779d74c1bb12b6668f3ab3ddd7837f3a4a00
|
||||
, 0x28382d747e3fd6cb2e0d8e8edd79c5313eed307a3517c11046245b1476e4f701
|
||||
, 0x0ca89aecd5675b77c8271765da98cfcb6875b3053d4742c9ff502861bd16ad28
|
||||
, 0x19046bc0b03ca90802ec83f212001e7ffd7f9224cfffae523451deb52eab3787
|
||||
, 0x036fd7dfa1c05110b3428e6abcc43e1de9abba915320c4a600f843bfb676ca51
|
||||
, 0x08f0a7abcb1a2f6595a9b7380c5028e3999db4fe5cb21892e5bb5cb11a7757ba
|
||||
, 0x0b614acc1ce3fbe9048f8385e4ee24c3843deea186bacea3c904c9f6340ad8cb
|
||||
, 0x00b2d98c5d988f9b41f2c98e017fc954a6ae423b2261575941f8eac8835d985c
|
||||
, 0x1457f18555b7973ba5b311d57ec5d77e936980b97f5973875f1f7cc765a4fc95
|
||||
, 0x002b453debc1bee525cb751bc10641a6b86f847d696418cf1144950982591bfa
|
||||
, 0x0c2af1abcc6ece77218315d2af445ccbfc6647b7af2510682882cc792c6bb8cf
|
||||
, 0x0e2825d9eb84b59902a1adb49ac0c2c291dee7c45d2e8c30369a4d595039e8ad
|
||||
, 0x297e2e86a8c672d39f3343b8dfce7a6f20f3571bfd5c8a28e3905aa2dcfeca44
|
||||
, 0x00d397281d902e49ec6504ba9186e806db9ad4fc8f86e7277aa7f1467eb6f9de
|
||||
, 0x2fb7c89c372d7e2050e7377ed471000c73544a2b9fd66557f3577c09cac98b4b
|
||||
, 0x16125247be4387a8c3e62490167f0cffdba02eda4f018d0b40639a13bb0cfef9
|
||||
, 0x2291fd9d442f2d9b97ab22f7d4d52c2a82e41f852cf620b144612650a39e26e8
|
||||
, 0x1eec61f16a275ae238540feaeeadfec56d32171b1cc393729d06f37f476fde71
|
||||
, 0x259ce871ba5dacbb48d8aed3d8513eef51558dc0b360f28c1a15dbfc5e7f6ca2
|
||||
, 0x2d3376a14ddbf95587e2f7567ff04fe13a3c7cb17363c8b9c5dd1d9262a210cb
|
||||
, 0x13b843d9f65f4cddd7ce10d9cad9b8b99ac5e9a8c4269288173a91c0f3c3b084
|
||||
, 0x0b52e9b2f1aa9fd204e4a42c481cc76c704783e34114b8e93e026a50fa9764e8
|
||||
, 0x1fd083229276c7f27d3ad941476b394ff37bd44d3a1e9caca1400d9077a2056c
|
||||
, 0x22743c328a6283f3ba7379af22c684c498568fd7ad9fad5151368c913197cbd9
|
||||
, 0x043007aefd9741070d95caaaba0c1b070e4eec8eef8c1e512c8e579c6ed64f76
|
||||
, 0x17ab175144f64bc843074f6b3a0c57c5dd2c954af8723c029ee642539496a7b3
|
||||
, 0x2befcad3d53fba5eeef8cae9668fed5c1e9e596a46e8458e218f7a665fddf4eb
|
||||
, 0x15151c4116d97de74bfa6ca3178f73c8fe8fe612c70c6f85a7a1551942cb71cc
|
||||
, 0x2ac40bf6c3176300a6835d5fc7cc4fd5e5d299fb1baa86487268ec1b9eedfa97
|
||||
, 0x0f151de1f01b4e24ffe04279318f0a68efabb485188f191e37e6915ff6059f6e
|
||||
, 0x2e43dffc34537535182aebac1ad7bf0a5533b88f65f9652f0ad584e2ffc4dd1f
|
||||
, 0x2ebabc2c37ef53d8b13b24a2a2b729d536735f58956125a3876da0664c2442d7
|
||||
, 0x0dc3beceb34e49f5ad7226dd202c5cf879dffcc9a6dd32a300e8f2a4b59edf03
|
||||
, 0x2f1ddeccce83adf68779c53b639871a8f81d4d00aefe1e812efce8ec999d457d
|
||||
, 0x1f63e41280ff5c021715d52b19780298ed8bd3d5eb506316b527e24149d4d4f1
|
||||
, 0x1b8c1252a5888f8cb2672effb5df49c633d3fd7183271488a1c40d0f88e7636e
|
||||
, 0x0f45697130f5498e2940568ef0d5e9e16b1095a6cdbb6411df20a973c605e70b
|
||||
, 0x0780ccc403cdd68983acbd34cda41cacfb2cf911a93076bc25587b4b0aed4929
|
||||
, 0x238d26ca97c691591e929f32199a643550f325f23a85d420080b289d7cecc9d4
|
||||
]
|
||||
|
||||
sb = SBox(inp[0] + round_consts[i])
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*sb + inp[1] + inp[2];
|
||||
out[1] = sb + 2*inp[1] + inp[2];
|
||||
out[2] = sb + inp[1] + 3*inp[2];
|
||||
return out
|
||||
|
||||
def ExternalRound(inp, i):
|
||||
out = [F(0) for j in range(3)]
|
||||
round_consts = [ [ F(0x2c4c51fd1bb9567c27e99f5712b49e0574178b41b6f0a476cddc41d242cf2b43)
|
||||
, F(0x1c5f8d18acb9c61ec6fcbfcda5356f1b3fdee7dc22c99a5b73a2750e5b054104)
|
||||
, F(0x2d3c1988b4541e4c045595b8d574e98a7c2820314a82e67a4e380f1c4541ba90 )
|
||||
]
|
||||
, [ F(0x052547dc9e6d936cab6680372f1734c39f490d0cb970e2077c82f7e4172943d3)
|
||||
, F(0x29d967f4002adcbb5a6037d644d36db91f591b088f69d9b4257694f5f9456bc2)
|
||||
, F(0x0350084b8305b91c426c25aeeecafc83fc5feec44b9636cb3b17d2121ec5b88a)
|
||||
]
|
||||
, [ F(0x1815d1e52a8196127530cc1e79f07a0ccd815fb5d94d070631f89f6c724d4cbe)
|
||||
, F(0x17b5ba882530af5d70466e2b434b0ccb15b7a8c0138d64455281e7724a066272)
|
||||
, F(0x1c859b60226b443767b73cd1b08823620de310bc49ea48662626014cea449aee)
|
||||
]
|
||||
, [ F(0x1b26e7f0ac7dd8b64c2f7a1904c958bb48d2635478a90d926f5ff2364effab37)
|
||||
, F(0x2da7f36850e6c377bdcdd380efd9e7c419555d3062b0997952dfbe5c54b1a22e)
|
||||
, F(0x17803c56450e74bc6c7ff97275390c017f682db11f3f4ca6e1f714efdfb9bd66)
|
||||
]
|
||||
, [ F(0x25672a14b5d085e31a30a7e1d5675ebfab034fb04dc2ec5e544887523f98dede)
|
||||
, F(0x0cf702434b891e1b2f1d71883506d68cdb1be36fa125674a3019647b3a98accd)
|
||||
, F(0x1837e75235ff5d112a5eddf7a4939448748339e7b5f2de683cf0c0ae98bdfbb3)
|
||||
]
|
||||
, [ F(0x1cd8a14cff3a61f04197a083c6485581a7d836941f6832704837a24b2d15613a)
|
||||
, F(0x266f6d85be0cef2ece525ba6a54b647ff789785069882772e6cac8131eecc1e4)
|
||||
, F(0x0538fde2183c3f5833ecd9e07edf30fe977d28dd6f246d7960889d9928b506b3)
|
||||
]
|
||||
, [ F(0x07a0693ff41476abb4664f3442596aa8399fdccf245d65882fce9a37c268aa04)
|
||||
, F(0x11eb49b07d33de2bd60ea68e7f652beda15644ed7855ee5a45763b576d216e8e)
|
||||
, F(0x08f8887da6ce51a8c06041f64e22697895f34bacb8c0a39ec12bf597f7c67cfc)
|
||||
]
|
||||
, [ F(0x2a912ec610191eb7662f86a52cc64c0122bd5ba762e1db8da79b5949fdd38092)
|
||||
, F(0x2031d7fd91b80857aa1fef64e23cfad9a9ba8fe8c8d09de92b1edb592a44c290)
|
||||
, F(0x0f81ebce43c47711751fa64d6c007221016d485641c28c507d04fd3dc7fba1d2)
|
||||
]
|
||||
]
|
||||
|
||||
sb = [F(0) for j in range(3)]
|
||||
for j in range(3):
|
||||
sb[j] = SBox(F(inp[j] + round_consts[i][j]))
|
||||
out = [F(0) for j in range(3)]
|
||||
out[0] = 2*sb[0] + sb[1] + sb[2]
|
||||
out[1] = sb[0] + 2*sb[1] + sb[2]
|
||||
out[2] = sb[0]+ sb[1] + 2*sb[2]
|
||||
return out
|
||||
|
||||
def LinearLayer(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*inp[0] + inp[1] + inp[2]
|
||||
out[1] = inp[0] + 2*inp[1] + inp[2]
|
||||
out[2] = inp[0] + inp[1] + 2*inp[2]
|
||||
return out
|
||||
|
||||
def Permutation(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
|
||||
state = LinearLayer(inp)
|
||||
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k)
|
||||
for k in range(56):
|
||||
state = InternalRound(state, k)
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k+4)
|
||||
return state
|
||||
|
||||
def Compression(inp):
|
||||
return Permutation([inp[0],inp[1],F(0)])
|
||||
|
||||
def PoseidonSponge(data, capacity, output_len):
|
||||
rate = 3 - capacity;
|
||||
output = [F(0) for i in range(output_len)]
|
||||
assert( capacity > 0 )
|
||||
assert( rate > 0 )
|
||||
assert( capacity < 3 )
|
||||
assert( rate < 3 )
|
||||
|
||||
# round up to rate the input + 1 field element ("10*" padding)
|
||||
nblocks = ((len(data) + 1) + (rate-1)) // rate;
|
||||
nout = (output_len + (rate-1)) // rate;
|
||||
padded_len = nblocks * rate;
|
||||
|
||||
padded = []
|
||||
for i in range(len(data)):
|
||||
padded.append(F(data[i]))
|
||||
padded.append(F(1))
|
||||
for i in range(len(data)+1,padded_len):
|
||||
padded.append(F(0))
|
||||
|
||||
civ = F(2**64 + 256*3 + rate)
|
||||
|
||||
state = [F(0),F(0),F(civ)]
|
||||
sorbed = [F(0) for j in range(rate)]
|
||||
|
||||
for m in range(nblocks):
|
||||
for i in range(rate):
|
||||
a = state[i]
|
||||
b = padded[m*rate+i]
|
||||
sorbed[i] = a + b
|
||||
state = Permutation(sorbed[0:rate] + state[rate:3])
|
||||
|
||||
q = min(rate, output_len)
|
||||
for i in range(q):
|
||||
output[i] = state[i]
|
||||
out_ptr = rate
|
||||
|
||||
for n in range(1,nout):
|
||||
state[nblocks+n] = Permutation(state[nblocks+n-1])
|
||||
q = min(rate, output_len-out_ptr)
|
||||
for i in range(q):
|
||||
output[out_ptr+i] = state[nblocks+n][i]
|
||||
out_ptr += rate
|
||||
|
||||
return output
|
||||
|
||||
R = RealField(500) #Real numbers with precision 500 bits
|
||||
|
||||
value = F(randrange(0,2**32,1))
|
||||
state = F(randrange(0,p,1))
|
||||
nonce = F(randrange(0,p,1))
|
||||
sk = F(randrange(0,p,1))
|
||||
|
||||
pending_balance = F(randrange(-2**10,2**10,1))
|
||||
|
||||
with open("input.json", "w") as file:
|
||||
file.write('{\n\t"state":\t\t\t\t\t\t"'+str(state)+'",')
|
||||
file.write('\n\t"value":\t\t\t\t\t\t"'+str(value)+'",')
|
||||
file.write('\n\t"nonce" :\t\t\t\t\t\t"'+str(nonce)+'",')
|
||||
file.write('\n\t"secret_key" :\t\t\t\t\t\t"'+str(sk)+'",')
|
||||
file.write('\n\t"pending_balance" :\t\t\t\t\t\t"'+str(pending_balance)+'"}')
|
||||
@ -212,7 +212,7 @@ nInputs = int(sys.argv[Integer(1)])
|
||||
nOutputs = int(sys.argv[Integer(2)])
|
||||
|
||||
value_in = [F(randrange(0,10000,1) )for i in range(nInputs) ]
|
||||
unit = F(161796427070100155131822184769584603407573991022311108406630770340454367555)
|
||||
unit = F(19676183153323264216568033390884511718872104179761154996527087027500271872825)
|
||||
state_in = [F(randrange(0,p,1)) for i in range(nInputs) ]
|
||||
zone_in = [F(randrange(0,p,1)) for i in range(nInputs) ]
|
||||
note_nonce_in = [F(randrange(0,p,1)) for i in range(nInputs)]
|
||||
@ -239,7 +239,9 @@ zone_out = [F(randrange(0,p,1)) for i in range(nOutputs) ]
|
||||
|
||||
|
||||
with open("input.json", "w") as file:
|
||||
file.write('{\n\t"state_in" :\t\t\t\t\t[')
|
||||
file.write('{\n\t"minting_covenant" :\t\t\t\t"'+str(0)+'",')
|
||||
file.write('\n\t"burning_covenant" :\t\t\t\t"'+str(0)+'",')
|
||||
file.write('\n\t"state_in" :\t\t\t\t\t[')
|
||||
for i in range(nInputs):
|
||||
file.write('"')
|
||||
file.write(str(state_in[i]))
|
||||
|
||||
@ -4,32 +4,67 @@ pragma circom 2.1.9;
|
||||
include "../ledger/notes.circom";
|
||||
include "../misc/constants.circom";
|
||||
|
||||
template proof_of_ownership(){
|
||||
signal input state;
|
||||
signal input value;
|
||||
signal input nonce;
|
||||
signal input zoneID;
|
||||
signal input secret_key;
|
||||
template proof_of_private_note_ownership(nInput){
|
||||
signal input state[nInput];
|
||||
signal input value[nInput];
|
||||
signal input nonce[nInput];
|
||||
signal input zoneID[nInput];
|
||||
signal input secret_key[nInput];
|
||||
signal input minting_covenant[nInput];
|
||||
signal input transfer_covenant[nInput];
|
||||
signal input burning_covenant[nInput];
|
||||
|
||||
signal input attached_data;
|
||||
|
||||
signal output commitment;
|
||||
signal output commitment[nInput];
|
||||
|
||||
component pk = derive_public_key();
|
||||
pk.secret_key <== secret_key;
|
||||
component pk[nInput];
|
||||
for(var i =0; i<nInput; i++){
|
||||
pk[i] = derive_public_key();
|
||||
pk[i].secret_key <== secret_key[i];
|
||||
}
|
||||
|
||||
component cm = commitment();
|
||||
cm.state <== state;
|
||||
cm.value <== value;
|
||||
component nmo = NMO();
|
||||
cm.unit <== nmo.out;
|
||||
cm.nonce <== nonce;
|
||||
cm.zoneID <== zoneID;
|
||||
cm.public_key <== pk.out;
|
||||
component unit[nInput];
|
||||
for(var i=0; i< nInput; i++){
|
||||
unit[i] = derive_unit();
|
||||
unit[i].minting_covenant <== minting_covenant[i];
|
||||
unit[i].transfer_covenant <== transfer_covenant[i];
|
||||
unit[i].burning_covenant <== burning_covenant[i];
|
||||
}
|
||||
|
||||
component cm[nInput];
|
||||
for(var i =0; i< nInput; i++){
|
||||
cm[i] = commitment();
|
||||
cm[i].state <== state[i];
|
||||
cm[i].value <== value[i];
|
||||
cm[i].unit <== unit[i].out;
|
||||
cm[i].nonce <== nonce[i];
|
||||
cm[i].zoneID <== zoneID[i];
|
||||
cm[i].public_key <== pk[i].out;
|
||||
}
|
||||
|
||||
// dummy constraint to avoid unused public input to be erased after compilation optimisation
|
||||
signal dummy;
|
||||
dummy <== attached_data * attached_data;
|
||||
}
|
||||
|
||||
component main {public [zoneID,attached_data]}= proof_of_ownership();
|
||||
template proof_of_public_note_ownership(nInput){
|
||||
signal input secret_key[nInput];
|
||||
|
||||
signal input attached_data;
|
||||
|
||||
signal output public_key[nInput];
|
||||
|
||||
component pk[nInput];
|
||||
for(var i =0; i<nInput; i++){
|
||||
pk[i] = derive_public_key();
|
||||
pk[i].secret_key <== secret_key[i];
|
||||
public_key[i] <== pk[i].out;
|
||||
}
|
||||
|
||||
// dummy constraint to avoid unused public input to be erased after compilation optimisation
|
||||
signal dummy;
|
||||
dummy <== attached_data * attached_data;
|
||||
}
|
||||
|
||||
component main {public [attached_data]}= proof_of_public_note_ownership(1);
|
||||
@ -57,7 +57,12 @@ template derive_entropy(){
|
||||
}
|
||||
|
||||
|
||||
template staking_proof_of_leadership(){
|
||||
template proof_of_leadership(){
|
||||
signal input selector; // 0 if the note is private and 1 if the note is public
|
||||
|
||||
// Check that the selector is indeed a bit
|
||||
selector * (1- selector) === 0;
|
||||
|
||||
signal input slot;
|
||||
signal input epoch_nonce;
|
||||
signal input t0;
|
||||
@ -70,10 +75,13 @@ template staking_proof_of_leadership(){
|
||||
signal input cm_aged_selectors[32]; // must be bits
|
||||
signal input commitments_aged_root;
|
||||
|
||||
//Part of the commitment proof of membership to prove aged
|
||||
signal input cm_unspent_nodes[32];
|
||||
signal input cm_unspent_selectors[32]; // must be bits
|
||||
signal input commitments_unspent_root;
|
||||
|
||||
//Part of the nullifer proof of non-membership/commitment proof of membership to prove the note is unspent
|
||||
signal input nf_previous; // Can be mocked and set to any value if selector == 1 as long as previous < nullifier < next
|
||||
signal input nf_next;
|
||||
signal input unspent_nodes[32];
|
||||
signal input unspent_selectors[32]; // must be bits
|
||||
signal input unspent_root; // It's either the nullifier (if selector = 0) or the commitment root of the last state
|
||||
|
||||
//Part of the secret key
|
||||
signal input starting_slot;
|
||||
@ -116,6 +124,12 @@ template staking_proof_of_leadership(){
|
||||
cm.public_key <== pk.out;
|
||||
|
||||
|
||||
// Derive the nullifier from the commitment and the secret key
|
||||
component nf = nullifier();
|
||||
nf.commitment <== cm.out;
|
||||
nf.secret_key <== sk.out;
|
||||
|
||||
|
||||
// Check commitment membership (is aged enough)
|
||||
//First check selectors are indeed bits
|
||||
for(var i = 0; i < 32; i++){
|
||||
@ -153,19 +167,35 @@ template staking_proof_of_leadership(){
|
||||
winning.out === 1;
|
||||
|
||||
|
||||
// Check commitment membership (is unspent)
|
||||
// Check that the note is unspent
|
||||
//First check selectors are indeed bits
|
||||
for(var i = 0; i < 32; i++){
|
||||
cm_unspent_selectors[i] * (1 - cm_unspent_selectors[i]) === 0;
|
||||
unspent_selectors[i] * (1 - unspent_selectors[i]) === 0;
|
||||
}
|
||||
//Then check the proof of membership
|
||||
component cm_unspent_membership = proof_of_membership(32);
|
||||
//Then check the proof of membership (that the nullifier leaf is in the set or that the commitment is)
|
||||
component unspent_membership = proof_of_membership(32);
|
||||
for(var i = 0; i < 32; i++){
|
||||
cm_unspent_membership.nodes[i] <== cm_unspent_nodes[i];
|
||||
cm_unspent_membership.selector[i] <== cm_unspent_selectors[i];
|
||||
unspent_membership.nodes[i] <== unspent_nodes[i];
|
||||
unspent_membership.selector[i] <== unspent_selectors[i];
|
||||
}
|
||||
cm_unspent_membership.root <== commitments_unspent_root;
|
||||
cm_unspent_membership.leaf <== cm.out;
|
||||
unspent_membership.root <== unspent_root;
|
||||
//Compute the leaf if it's a private note representing previous nf pointing to next in the IMT
|
||||
component hash = Poseidon2_hash(2);
|
||||
hash.inp[0] <== nf_previous;
|
||||
hash.inp[1] <== nf_next;
|
||||
unspent_membership.leaf <== (cm.out - hash.out) * selector + hash.out; // the leaf is then either the commitment or the leaf computed before
|
||||
|
||||
// Check that nullifier stictly falls between previous and next if the note is private.
|
||||
// If the note is public previous and next can be any values such that previous < nullifier < next
|
||||
component comparator[2];
|
||||
comparator[0] = SafeFullLessThan();
|
||||
comparator[0].a <== nf_previous;
|
||||
comparator[0].b <== nf.out;
|
||||
comparator[0].out === 1;
|
||||
comparator[1] = SafeFullLessThan();
|
||||
comparator[1].a <== nf.out;
|
||||
comparator[1].b <== nf_next;
|
||||
comparator[1].out === 1;
|
||||
|
||||
|
||||
// Check the knowledge of the secret at position slot - starting_slot
|
||||
@ -196,4 +226,4 @@ template staking_proof_of_leadership(){
|
||||
entropy_contrib <== entropy.out;
|
||||
}
|
||||
|
||||
component main {public [slot,epoch_nonce,t0,t1,commitments_aged_root,commitments_unspent_root,one_time_key]}= staking_proof_of_leadership();
|
||||
component main {public [slot,epoch_nonce,t0,t1,commitments_aged_root,unspent_root,one_time_key]}= proof_of_leadership();
|
||||
@ -1,44 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../ledger/notes.circom";
|
||||
include "../misc/constants.circom";
|
||||
include "../circomlib/circuits/comparators.circom";
|
||||
|
||||
template proof_of_funds(){
|
||||
signal input state;
|
||||
signal input value; // 64 bits
|
||||
signal input nonce;
|
||||
signal input zoneID;
|
||||
signal input secret_key;
|
||||
|
||||
signal input threshold; // 64 bits
|
||||
signal input attached_data;
|
||||
|
||||
signal output commitment;
|
||||
|
||||
component pk = derive_public_key();
|
||||
pk.secret_key <== secret_key;
|
||||
|
||||
component cm = commitment();
|
||||
cm.state <== state;
|
||||
cm.value <== value;
|
||||
component nmo = NMO();
|
||||
cm.unit <== nmo.out;
|
||||
cm.nonce <== nonce;
|
||||
cm.zoneID <== zoneID;
|
||||
cm.public_key <== pk.out;
|
||||
|
||||
// Check that the value is greater than the inputed threshold
|
||||
component comparator = GreaterThan(64);
|
||||
comparator.in[0] <== value;
|
||||
comparator.in[1] <== threshold;
|
||||
comparator.out === 1;
|
||||
|
||||
|
||||
// dummy constraint to avoid unused public input to be erased after compilation optimisation
|
||||
signal dummy;
|
||||
dummy <== attached_data * attached_data;
|
||||
}
|
||||
|
||||
component main {public [zoneID,threshold,attached_data]}= proof_of_funds();
|
||||
@ -1,51 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../ledger/notes.circom";
|
||||
include "../misc/constants.circom";
|
||||
|
||||
template note_refreshment(){
|
||||
|
||||
//note
|
||||
signal input state;
|
||||
signal input value;
|
||||
signal input nonce;
|
||||
signal input previous_sk;
|
||||
signal input new_sk;
|
||||
signal input zoneID;
|
||||
|
||||
signal output previous_commitment;
|
||||
signal output new_commitment;
|
||||
|
||||
// Derive the two public keys proving ownership of the keys
|
||||
component previous_pk = derive_public_key();
|
||||
component new_pk = derive_public_key();
|
||||
previous_pk.secret_key <== previous_sk;
|
||||
new_pk.secret_key <== new_sk;
|
||||
|
||||
component previous_cm = commitment();
|
||||
component new_cm = commitment();
|
||||
component nmo = NMO();
|
||||
|
||||
// Derive the commitment of the note before changing the key
|
||||
previous_cm.state <== state;
|
||||
previous_cm.value <== value;
|
||||
previous_cm.unit <== nmo.out;
|
||||
previous_cm.nonce <== nonce;
|
||||
previous_cm.zoneID <== zoneID;
|
||||
previous_cm.public_key <== previous_pk.out;
|
||||
previous_commitment <== previous_cm.out;
|
||||
|
||||
|
||||
// Derive the new commitment after secret key modification
|
||||
// The ownership is the same because both secret keys are known
|
||||
new_cm.state <== state;
|
||||
new_cm.value <== value;
|
||||
new_cm.unit <== nmo.out;
|
||||
new_cm.nonce <== nonce;
|
||||
new_cm.zoneID <== zoneID;
|
||||
new_cm.public_key <== new_pk.out;
|
||||
new_commitment <== new_cm.out;
|
||||
}
|
||||
|
||||
component main {public [zoneID]}= note_refreshment();
|
||||
@ -1,50 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../ledger/notes.circom";
|
||||
include "../misc/constants.circom";
|
||||
|
||||
template additive_note_slahsing(){
|
||||
|
||||
//note
|
||||
signal input state;
|
||||
signal input value;
|
||||
signal input nonce;
|
||||
signal input secret_key;
|
||||
|
||||
signal input pending_balance; // pending balance between 0 and 2**64 for rewards and p-2**64 and p for slashing
|
||||
|
||||
signal output previous_commitment;
|
||||
signal output new_commitment;
|
||||
|
||||
|
||||
component pk = derive_public_key();
|
||||
pk.secret_key <== secret_key;
|
||||
|
||||
component previous_cm = commitment();
|
||||
component new_cm = commitment();
|
||||
component nmo = NMO();
|
||||
component staking = STAKING();
|
||||
|
||||
// Derive the commitment of the note before changing the value
|
||||
previous_cm.state <== state;
|
||||
previous_cm.value <== value;
|
||||
previous_cm.unit <== nmo.out;
|
||||
previous_cm.nonce <== nonce;
|
||||
previous_cm.zoneID <== staking.out;
|
||||
previous_cm.public_key <== pk.out;
|
||||
previous_commitment <== previous_cm.out;
|
||||
|
||||
|
||||
// Derive the new commitment after secret key modification
|
||||
// The ownership is the same because both secret keys are known
|
||||
new_cm.state <== state;
|
||||
new_cm.value <== value + pending_balance;
|
||||
new_cm.unit <== nmo.out;
|
||||
new_cm.nonce <== nonce;
|
||||
new_cm.zoneID <== staking.out;
|
||||
new_cm.public_key <== pk.out;
|
||||
new_commitment <== new_cm.out;
|
||||
}
|
||||
|
||||
component main {public [pending_balance]}= additive_note_slahsing();
|
||||
@ -6,6 +6,9 @@ include "../misc/constants.circom";
|
||||
|
||||
template transfer(nInputs, nOutputs){
|
||||
|
||||
signal input minting_covenant; // Used to derive the unit and make sure the token use a no-op transfer covenant.
|
||||
signal input burning_covenant;
|
||||
|
||||
//consummed notes
|
||||
// notes themselves
|
||||
signal input state_in[nInputs];
|
||||
@ -30,6 +33,14 @@ template transfer(nInputs, nOutputs){
|
||||
signal input attached_data;
|
||||
|
||||
signal output balance;
|
||||
signal output unit; // Disclose the unit of the transaction
|
||||
|
||||
//Derive the unit
|
||||
component derive_unit = derive_unit();
|
||||
derive_unit.minting_covenant <== minting_covenant;
|
||||
derive_unit.transfer_covenant <== 0; // 0 encodes the fact that it's a no-op transfer covenant
|
||||
derive_unit.burning_covenant <== burning_covenant;
|
||||
unit <== derive_unit.out;
|
||||
|
||||
|
||||
// Verify the ownership of the consummed notes deriving the public keys from the secret keys
|
||||
@ -41,19 +52,17 @@ template transfer(nInputs, nOutputs){
|
||||
|
||||
|
||||
// Derive the commitments of the consummed notes
|
||||
component nmo = NMO(); // NMO token constant
|
||||
component cm_in[nInputs];
|
||||
for(var i =0; i<nInputs; i++){
|
||||
cm_in[i] = commitment();
|
||||
cm_in[i].state <== state_in[i];
|
||||
cm_in[i].value <== value_in[i];
|
||||
cm_in[i].unit <== nmo.out;
|
||||
cm_in[i].unit <== unit;
|
||||
cm_in[i].nonce <== nonce_in[i];
|
||||
cm_in[i].zoneID <== zoneID_in[i];
|
||||
cm_in[i].public_key <== pk[i].out;
|
||||
}
|
||||
|
||||
|
||||
// Derive the nullifiers of the consummed notes
|
||||
component nf[nInputs];
|
||||
for(var i=0; i<nInputs; i++){
|
||||
@ -88,7 +97,7 @@ template transfer(nInputs, nOutputs){
|
||||
cm_out[i] = commitment();
|
||||
cm_out[i].state <== state_out[i];
|
||||
cm_out[i].value <== value_out[i];
|
||||
cm_out[i].unit <== nmo.out;
|
||||
cm_out[i].unit <== unit;
|
||||
cm_out[i].nonce <== nonce_out[i];
|
||||
cm_out[i].zoneID <== zoneID_out[i];
|
||||
cm_out[i].public_key <== public_key_out[i];
|
||||
@ -110,4 +119,4 @@ template transfer(nInputs, nOutputs){
|
||||
|
||||
}
|
||||
|
||||
component main {public [zoneID_in,commitments_root,zoneID_out]}= transfer(1,1);
|
||||
component main {public [zoneID_in,commitments_root,zoneID_out]}= transfer(4,4);
|
||||
@ -53,3 +53,18 @@ template derive_public_key(){
|
||||
out <== hash.out;
|
||||
}
|
||||
|
||||
template derive_unit(){
|
||||
signal input minting_covenant;
|
||||
signal input transfer_covenant;
|
||||
signal input burning_covenant;
|
||||
signal output out;
|
||||
|
||||
component hash = Poseidon2_hash(4);
|
||||
component dst = NOMOS_UNIT();
|
||||
hash.inp[0] <== dst.out;
|
||||
hash.inp[1] <== minting_covenant;
|
||||
hash.inp[2] <== transfer_covenant;
|
||||
hash.inp[3] <== burning_covenant;
|
||||
out <== hash.out;
|
||||
}
|
||||
|
||||
|
||||
@ -25,13 +25,6 @@ template NOMOS_NONCE_CONTRIB(){
|
||||
}
|
||||
|
||||
|
||||
// int.from_bytes(hashlib.sha256(b"NMO").digest()[:-1], "little") = 161796427070100155131822184769584603407573991022311108406630770340454367555
|
||||
template NMO(){
|
||||
signal output out;
|
||||
out <== 161796427070100155131822184769584603407573991022311108406630770340454367555;
|
||||
}
|
||||
|
||||
|
||||
// int.from_bytes(hashlib.sha256(b"PAYMENT").digest()[:-1], "little") = 281646683567839822174419720505039861445414630574005374635737888376398200354
|
||||
template PAYMENT(){
|
||||
signal output out;
|
||||
@ -64,4 +57,18 @@ template NOMOS_NOTE_NF(){
|
||||
template NOMOS_KDF(){
|
||||
signal output out;
|
||||
out <== 355994159511987982411097843485998670968942801951585260613801918349630142543;
|
||||
}
|
||||
|
||||
|
||||
// int.from_bytes(hashlib.sha256(b"NOMOS_UNIT").digest()[:-1], "little") = 379867176337182448308325460959840323359954688990124617407218984660753645420
|
||||
template NOMOS_UNIT(){
|
||||
signal output out;
|
||||
out <== 379867176337182448308325460959840323359954688990124617407218984660753645420;
|
||||
}
|
||||
|
||||
|
||||
// Poseidon2(NOMOS_UNIT,0,0,0) = 19676183153323264216568033390884511718872104179761154996527087027500271872825
|
||||
template NMO(){
|
||||
signal output out;
|
||||
out <== 19676183153323264216568033390884511718872104179761154996527087027500271872825;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user