mirror of
https://github.com/logos-blockchain/logos-blockchain-pocs.git
synced 2026-02-23 22:43:18 +00:00
rename folder and reworked the transaction
This commit is contained in:
parent
39fdbd972f
commit
dab1ebd4bf
@ -205,89 +205,94 @@ def PoseidonSponge(data, capacity, output_len):
|
||||
R = RealField(500) #Real numbers with precision 500 bits
|
||||
|
||||
if len(sys.argv) != Integer(3):
|
||||
print("Usage: <script> <nInputs> <nOutputs> ")
|
||||
print("Usage: <script> <maxInputs> <maxOutputs> ")
|
||||
exit()
|
||||
|
||||
nInputs = int(sys.argv[Integer(1)])
|
||||
nOutputs = int(sys.argv[Integer(2)])
|
||||
maxInputs = int(sys.argv[Integer(1)])
|
||||
maxOutputs = int(sys.argv[Integer(2)])
|
||||
|
||||
value_in = [F(randrange(0,10000,1) )for i in range(nInputs) ]
|
||||
value_in = [F(randrange(0,10000,1) )for i in range(maxInputs) ]
|
||||
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)]
|
||||
sk_in = [F(randrange(0,p,1)) for i in range(nInputs)]
|
||||
pk_in = [ poseidon2_hash([F(355994159511987982411097843485998670968942801951585260613801918349630142543),sk_in[i]]) for i in range(nInputs) ]
|
||||
state_in = [F(randrange(0,p,1)) for i in range(maxInputs) ]
|
||||
zone_in = [F(randrange(0,p,1)) for i in range(maxInputs) ]
|
||||
note_nonce_in = [F(randrange(0,p,1)) for i in range(maxInputs)]
|
||||
sk_in = [F(randrange(0,p,1)) for i in range(maxInputs)]
|
||||
pk_in = [ poseidon2_hash([F(355994159511987982411097843485998670968942801951585260613801918349630142543),sk_in[i]]) for i in range(maxInputs) ]
|
||||
attached_data = F(randrange(0,p,1))
|
||||
|
||||
note_cm_in = [poseidon2_hash([F(181645510297841241569044198526601622686169271532834574969543446901055041748),state_in[i],value_in[i],unit,note_nonce_in[i],pk_in[i],zone_in[i]]) for i in range(nInputs) ]
|
||||
cm_nodes = [[F(randrange(0,p,1)) for i in range(32)] for j in range(nInputs) ]
|
||||
cm_selectors = [format(randrange(0,2**32,1),'032b') for i in range(nInputs) ]
|
||||
cm_root = [ note_cm_in[i] for i in range(nInputs) ]
|
||||
for j in range(nInputs):
|
||||
note_cm_in = [poseidon2_hash([F(181645510297841241569044198526601622686169271532834574969543446901055041748),state_in[i],value_in[i],unit,note_nonce_in[i],pk_in[i],zone_in[i]]) for i in range(maxInputs) ]
|
||||
cm_nodes = [[F(randrange(0,p,1)) for i in range(32)] for j in range(maxInputs) ]
|
||||
cm_selectors = [format(randrange(0,2**32,1),'032b') for i in range(maxInputs) ]
|
||||
cm_root = [ note_cm_in[i] for i in range(maxInputs) ]
|
||||
for j in range(maxInputs):
|
||||
for i in range(32):
|
||||
if int(cm_selectors[j][31-i]) == 0:
|
||||
cm_root[j] = poseidon2_hash([cm_root[j],cm_nodes[j][i]])
|
||||
else:
|
||||
cm_root[j] = poseidon2_hash([cm_nodes[j][i],cm_root[j]])
|
||||
|
||||
value_out = [F(randrange(0,10000,1) )for i in range(nOutputs) ]
|
||||
state_out = [F(randrange(0,p,1)) for i in range(nOutputs) ]
|
||||
note_nonce_out = [F(randrange(0,p,1)) for i in range(nOutputs)]
|
||||
pk_out = [ F(randrange(0,p,1)) for i in range(nOutputs)]
|
||||
zone_out = [F(randrange(0,p,1)) for i in range(nOutputs) ]
|
||||
value_out = [F(randrange(0,10000,1) )for i in range(maxOutputs) ]
|
||||
state_out = [F(randrange(0,p,1)) for i in range(maxOutputs) ]
|
||||
note_nonce_out = [F(randrange(0,p,1)) for i in range(maxOutputs)]
|
||||
pk_out = [ F(randrange(0,p,1)) for i in range(maxOutputs)]
|
||||
zone_out = [F(randrange(0,p,1)) for i in range(maxOutputs)]
|
||||
|
||||
is_a_input_note = [F(randrange(0,1,1)) for i in range(maxInputs)]
|
||||
is_a_output_note = [F(randrange(0,1,1)) for i in range(maxOutputs)]
|
||||
is_a_input_note[0] = F(1)
|
||||
is_a_output_note[0] = F(1)
|
||||
|
||||
|
||||
with open("input.json", "w") as file:
|
||||
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):
|
||||
for i in range(maxInputs):
|
||||
file.write('"')
|
||||
file.write(str(state_in[i]))
|
||||
file.write('"')
|
||||
if i == (nInputs-1):
|
||||
if i == (maxInputs-1):
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"value_in" :\t\t\t\t\t[')
|
||||
for i in range(nInputs):
|
||||
for i in range(maxInputs):
|
||||
file.write('"')
|
||||
file.write(str(value_in[i]))
|
||||
file.write('"')
|
||||
if i == (nInputs-1):
|
||||
if i == (maxInputs-1):
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"nonce_in" :\t\t\t\t\t[')
|
||||
for i in range(nInputs):
|
||||
for i in range(maxInputs):
|
||||
file.write('"')
|
||||
file.write(str(note_nonce_in[i]))
|
||||
file.write('"')
|
||||
if i == (nInputs-1):
|
||||
if i == (maxInputs-1):
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"secret_key_in" :\t\t\t\t\t[')
|
||||
for i in range(nInputs):
|
||||
for i in range(maxInputs):
|
||||
file.write('"')
|
||||
file.write(str(sk_in[i]))
|
||||
file.write('"')
|
||||
if i == (nInputs-1):
|
||||
if i == (maxInputs-1):
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"zoneID_in" :\t\t\t\t\t[')
|
||||
for i in range(nInputs):
|
||||
for i in range(maxInputs):
|
||||
file.write('"')
|
||||
file.write(str(zone_in[i]))
|
||||
file.write('"')
|
||||
if i == (nInputs-1):
|
||||
if i == (maxInputs-1):
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"cm_nodes" :\t\t\t\t\t[')
|
||||
for i in range(nInputs):
|
||||
for i in range(maxInputs):
|
||||
file.write('\n\t\t\t\t\t\t[')
|
||||
for j in range(32):
|
||||
file.write('"')
|
||||
@ -297,12 +302,12 @@ with open("input.json", "w") as file:
|
||||
file.write(']')
|
||||
else:
|
||||
file.write(',')
|
||||
if i == (nInputs-1):
|
||||
if i == (maxInputs-1):
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"cm_selectors" :\t\t\t\t\t[')
|
||||
for i in range(nInputs):
|
||||
for i in range(maxInputs):
|
||||
file.write('\n\t\t\t\t\t\t[')
|
||||
for j in range(32):
|
||||
file.write('"')
|
||||
@ -312,62 +317,80 @@ with open("input.json", "w") as file:
|
||||
file.write(']')
|
||||
else:
|
||||
file.write(',')
|
||||
if i == (nInputs-1):
|
||||
if i == (maxInputs-1):
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"commitments_root" :\t\t\t\t\t[')
|
||||
for i in range(nInputs):
|
||||
for i in range(maxInputs):
|
||||
file.write('"')
|
||||
file.write(str(cm_root[i]))
|
||||
file.write('"')
|
||||
if i == (nInputs-1):
|
||||
if i == (maxInputs-1):
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"is_a_input_note" :\t\t\t\t\t[')
|
||||
for i in range(maxInputs):
|
||||
file.write('"')
|
||||
file.write(str(is_a_input_note[i]))
|
||||
file.write('"')
|
||||
if i == (maxInputs-1):
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"attached_data" :\t\t\t\t\t\t"'+str(attached_data)+'",')
|
||||
file.write('\n\t"state_out" :\t\t\t\t\t[')
|
||||
for i in range(nOutputs):
|
||||
for i in range(maxOutputs):
|
||||
file.write('"')
|
||||
file.write(str(state_out[i]))
|
||||
file.write('"')
|
||||
if i == (nOutputs-1):
|
||||
if i == (maxOutputs-1):
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"value_out" :\t\t\t\t\t[')
|
||||
for i in range(nOutputs):
|
||||
for i in range(maxOutputs):
|
||||
file.write('"')
|
||||
file.write(str(value_out[i]))
|
||||
file.write('"')
|
||||
if i == (nOutputs-1):
|
||||
if i == (maxOutputs-1):
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"nonce_out" :\t\t\t\t\t[')
|
||||
for i in range(nOutputs):
|
||||
for i in range(maxOutputs):
|
||||
file.write('"')
|
||||
file.write(str(note_nonce_out[i]))
|
||||
file.write('"')
|
||||
if i == (nOutputs-1):
|
||||
if i == (maxOutputs-1):
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"public_key_out" :\t\t\t\t\t[')
|
||||
for i in range(nOutputs):
|
||||
for i in range(maxOutputs):
|
||||
file.write('"')
|
||||
file.write(str(pk_out[i]))
|
||||
file.write('"')
|
||||
if i == (nOutputs-1):
|
||||
if i == (maxOutputs-1):
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"is_a_output_note" :\t\t\t\t\t[')
|
||||
for i in range(maxOutputs):
|
||||
file.write('"')
|
||||
file.write(str(is_a_output_note[i]))
|
||||
file.write('"')
|
||||
if i == (maxOutputs-1):
|
||||
file.write('],')
|
||||
else:
|
||||
file.write(',')
|
||||
file.write('\n\t"zoneID_out" :\t\t\t\t\t[')
|
||||
for i in range(nOutputs):
|
||||
for i in range(maxOutputs):
|
||||
file.write('"')
|
||||
file.write(str(zone_out[i]))
|
||||
file.write('"')
|
||||
if i == (nOutputs-1):
|
||||
if i == (maxOutputs-1):
|
||||
file.write(']}')
|
||||
else:
|
||||
file.write(',')
|
||||
@ -4,36 +4,37 @@ pragma circom 2.1.9;
|
||||
include "../ledger/notes.circom";
|
||||
include "../misc/constants.circom";
|
||||
|
||||
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 spending_covenant[nInput];
|
||||
signal input burning_covenant[nInput];
|
||||
template proof_of_private_note_ownership(maxInput){
|
||||
signal input state[maxInput];
|
||||
signal input value[maxInput];
|
||||
signal input nonce[maxInput];
|
||||
signal input zoneID[maxInput];
|
||||
signal input secret_key[maxInput];
|
||||
signal input minting_covenant[maxInput];
|
||||
signal input spending_covenant[maxInput];
|
||||
signal input burning_covenant[maxInput];
|
||||
signal input is_an_input[maxInput];
|
||||
|
||||
signal input attached_data;
|
||||
|
||||
signal output commitment[nInput];
|
||||
signal output commitment[maxInput];
|
||||
|
||||
component pk[nInput];
|
||||
for(var i =0; i<nInput; i++){
|
||||
component pk[maxInput];
|
||||
for(var i =0; i<maxInput; i++){
|
||||
pk[i] = derive_public_key();
|
||||
pk[i].secret_key <== secret_key[i];
|
||||
}
|
||||
|
||||
component unit[nInput];
|
||||
for(var i=0; i< nInput; i++){
|
||||
component unit[maxInput];
|
||||
for(var i=0; i< maxInput; i++){
|
||||
unit[i] = derive_unit();
|
||||
unit[i].minting_covenant <== minting_covenant[i];
|
||||
unit[i].spending_covenant <== spending_covenant[i];
|
||||
unit[i].burning_covenant <== burning_covenant[i];
|
||||
}
|
||||
|
||||
component cm[nInput];
|
||||
for(var i =0; i< nInput; i++){
|
||||
component cm[maxInput];
|
||||
for(var i =0; i< maxInput; i++){
|
||||
cm[i] = commitment();
|
||||
cm[i].state <== state[i];
|
||||
cm[i].value <== value[i];
|
||||
@ -48,15 +49,15 @@ template proof_of_private_note_ownership(nInput){
|
||||
dummy <== attached_data * attached_data;
|
||||
}
|
||||
|
||||
template proof_of_public_note_ownership(nInput){
|
||||
signal input secret_key[nInput];
|
||||
template proof_of_public_note_ownership(maxInput){
|
||||
signal input secret_key[maxInput];
|
||||
|
||||
signal input attached_data;
|
||||
|
||||
signal output public_key[nInput];
|
||||
signal output public_key[maxInput];
|
||||
|
||||
component pk[nInput];
|
||||
for(var i =0; i<nInput; i++){
|
||||
component pk[maxInput];
|
||||
for(var i =0; i<maxInput; i++){
|
||||
pk[i] = derive_public_key();
|
||||
pk[i].secret_key <== secret_key[i];
|
||||
public_key[i] <== pk[i].out;
|
||||
@ -4,32 +4,35 @@ pragma circom 2.1.9;
|
||||
include "../ledger/notes.circom";
|
||||
include "../misc/constants.circom";
|
||||
|
||||
template transfer(nInputs, nOutputs){
|
||||
template shielded_transaction(maxInputs, maxOutputs){
|
||||
|
||||
signal input minting_covenant; // Used to derive the unit and make sure the token use a no-op transfer covenant.
|
||||
signal input minting_covenant; // Used to derive the unit and make sure the token use a no-op spending covenant.
|
||||
signal input burning_covenant;
|
||||
|
||||
//consummed notes
|
||||
// notes themselves
|
||||
signal input state_in[nInputs];
|
||||
signal input value_in[nInputs];
|
||||
signal input nonce_in[nInputs];
|
||||
signal input secret_key_in[nInputs];
|
||||
signal input zoneID_in[nInputs];
|
||||
signal input state_in[maxInputs];
|
||||
signal input value_in[maxInputs];
|
||||
signal input nonce_in[maxInputs];
|
||||
signal input secret_key_in[maxInputs];
|
||||
signal input zoneID_in[maxInputs];
|
||||
// proof of commitment membership
|
||||
signal input cm_nodes[nInputs][32];
|
||||
signal input cm_selectors[nInputs][32]; // must be bits
|
||||
signal input commitments_root[nInputs];
|
||||
signal output nullifier[nInputs];
|
||||
signal input cm_nodes[maxInputs][32];
|
||||
signal input cm_selectors[maxInputs][32]; // must be bits
|
||||
signal input commitments_root[maxInputs];
|
||||
signal input is_a_input_note[maxInputs]; // Selector to say if note i is a real entry or a dummy input, must be 0 or 1
|
||||
signal output nullifier[maxInputs]; // /!\ It needs to be checked outside the circuit by the validators
|
||||
// Padding can be realized by repeating the same note on selector 0 (validators will ignore the nullifier)
|
||||
|
||||
//created notes
|
||||
signal input state_out[nOutputs];
|
||||
signal input value_out[nOutputs];
|
||||
signal input nonce_out[nOutputs];
|
||||
signal input public_key_out[nOutputs];
|
||||
signal input zoneID_out[nOutputs];
|
||||
signal output commitments[nOutputs];
|
||||
|
||||
signal input state_out[maxOutputs];
|
||||
signal input value_out[maxOutputs];
|
||||
signal input nonce_out[maxOutputs];
|
||||
signal input public_key_out[maxOutputs];
|
||||
signal input zoneID_out[maxOutputs];
|
||||
signal input is_a_output_note[maxOutputs]; // Selector to say if note i is a real output or a dummy output, must be 0 or 1
|
||||
signal output commitments[maxOutputs]; // /!\ It needs to be checked outside the circuit by the validators
|
||||
// Padding can be realized by repeating the same note on selector 0 (validators will ignore the commitment)
|
||||
signal input attached_data;
|
||||
|
||||
signal output balance;
|
||||
@ -38,22 +41,22 @@ template transfer(nInputs, nOutputs){
|
||||
//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.spending_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
|
||||
component pk[nInputs];
|
||||
for(var i =0; i<nInputs; i++){
|
||||
component pk[maxInputs];
|
||||
for(var i =0; i<maxInputs; i++){
|
||||
pk[i] = derive_public_key();
|
||||
pk[i].secret_key <== secret_key_in[i];
|
||||
}
|
||||
|
||||
|
||||
// Derive the commitments of the consummed notes
|
||||
component cm_in[nInputs];
|
||||
for(var i =0; i<nInputs; i++){
|
||||
component cm_in[maxInputs];
|
||||
for(var i =0; i<maxInputs; i++){
|
||||
cm_in[i] = commitment();
|
||||
cm_in[i].state <== state_in[i];
|
||||
cm_in[i].value <== value_in[i];
|
||||
@ -64,8 +67,8 @@ template transfer(nInputs, nOutputs){
|
||||
}
|
||||
|
||||
// Derive the nullifiers of the consummed notes
|
||||
component nf[nInputs];
|
||||
for(var i=0; i<nInputs; i++){
|
||||
component nf[maxInputs];
|
||||
for(var i=0; i<maxInputs; i++){
|
||||
nf[i] = nullifier();
|
||||
nf[i].commitment <== cm_in[i].out;
|
||||
nf[i].secret_key <== secret_key_in[i];
|
||||
@ -74,8 +77,8 @@ template transfer(nInputs, nOutputs){
|
||||
|
||||
|
||||
// Prove the commitment membership against the chosen root(s)
|
||||
component cm_membership[nInputs];
|
||||
for(var i =0; i< nInputs; i++){
|
||||
component cm_membership[maxInputs];
|
||||
for(var i =0; i< maxInputs; i++){
|
||||
//First check selectors are indeed bits
|
||||
for(var j = 0; j < 32; j++){
|
||||
cm_selectors[i][j] * (1 - cm_selectors[i][j]) === 0;
|
||||
@ -92,8 +95,8 @@ template transfer(nInputs, nOutputs){
|
||||
|
||||
|
||||
// Derive the commitments of the created notes
|
||||
component cm_out[nOutputs];
|
||||
for(var i =0; i<nOutputs; i++){
|
||||
component cm_out[maxOutputs];
|
||||
for(var i =0; i<maxOutputs; i++){
|
||||
cm_out[i] = commitment();
|
||||
cm_out[i].state <== state_out[i];
|
||||
cm_out[i].value <== value_out[i];
|
||||
@ -104,14 +107,15 @@ template transfer(nInputs, nOutputs){
|
||||
commitments[i] <== cm_out[i].out;
|
||||
}
|
||||
|
||||
var b = 0;
|
||||
for(var i = 0; i< nInputs; i++){
|
||||
b += value_in[i];
|
||||
signal b[maxInputs + maxInputs];
|
||||
b[0] <== value_in[0] * is_a_input_note[0];
|
||||
for(var i = 1; i< maxInputs; i++){
|
||||
b[i] <== b[i-1] + value_in[i] * is_a_input_note[i];
|
||||
}
|
||||
for(var i =0; i< nOutputs; i++){
|
||||
b -= value_out[i];
|
||||
for(var i =0; i< maxOutputs; i++){
|
||||
b[i + maxInputs] <== b[maxInputs + i - 1] - value_out[i] * is_a_output_note[i];
|
||||
}
|
||||
balance <== b;
|
||||
balance <== b[maxInputs + maxOutputs - 1];
|
||||
|
||||
//dummy quadratic contraints to avoid optimisation erasing the public input
|
||||
signal dummy;
|
||||
@ -119,4 +123,4 @@ template transfer(nInputs, nOutputs){
|
||||
|
||||
}
|
||||
|
||||
component main {public [zoneID_in,commitments_root,zoneID_out]}= transfer(4,4);
|
||||
component main {public [zoneID_in,is_a_input_note,is_a_output_note,commitments_root,zoneID_out]}= shielded_transaction(4,4);
|
||||
Loading…
x
Reference in New Issue
Block a user