attestation icon indicating copy to clipboard operation
attestation copied to clipboard

produce a view function to test useDevconTicket

Open SmartLayer opened this issue 3 years ago • 3 comments

which has

getTicketHolderAddress(bytes UseDevconTicket)

The contract has to be deployed with the issuer's public key. Source code of the contract goes to src/main/solidity. (the capacity to update such key can be added later).

It returns the ticket holder's address. Such an address can be obtained by:

Get the public key in SEC1 2.3.4 format

UseDevconTicket.MyAttestation
.subjectPublicKeyInfo
.subjectPublicKeyInfoValue
.subjectPubilicKey

Get the Ethereum address

  1. check if the leading byte is 0x04 - throw up if it isn't (unless you are keen on implementing the full SEC1 spec)
  2. remove the leading byte and Keccek3 hash the rest 64 bytes
  3. return the first 160 bites as Ethereum address

Verifying UseDevconTicket

The zk proof in it must be verified otherwise the view function should err.

DevconTicket

The smart contract also must verify the DevconTicket otherwise the view function should err.

https://github.com/TokenScript/attestation/blob/main/data-modules/src/UseDevconTicket.asd

which contains SignedDevconTicket, which can be found here:

$ openssl asn1parse -inform DER < build/test-results/signed-devcon-ticket.der 
    0:d=0  hl=3 l= 153 cons: SEQUENCE          
    3:d=1  hl=2 l=  11 cons: SEQUENCE          
    5:d=2  hl=2 l=   1 prim: INTEGER           :06
    8:d=2  hl=2 l=   3 prim: INTEGER           :BE06
   13:d=2  hl=2 l=   1 prim: INTEGER           :00
   16:d=1  hl=2 l=  65 prim: OCTET STRING      [HEX DUMP]:04206430CAE202E5FAB41CE54B74725E454FF808720A039037D8403D95FEFDC035122C95BFD2AE1A48A3F42F0B8E78FB792351ADE20A2209A31F4E90DC61A4D50F
   83:d=1  hl=2 l=  71 prim: BIT STRING        

You can open it up with javascript:

$ nodejs src/test/javascript/ParserSerializerTest.js 
SignedDevconTicket {
  ticket: DevconTicket { devconId: 6n, ticketId: 48646n, ticketClass: 0n },
  commitment: ArrayBuffer {
    [Uint8Contents]: <04 20 64 30 ca e2 02 e5 fa b4 1c e5 4b 74 72 5e 45 4f f8 08 72 0a 03 90 37 d8 40 3d 95 fe fd c0 35 12 2c 95 bf d2 ae 1a 48 a3 f4 2f 0b 8e 78 fb 79 23 51 ad e2 0a 22 09 a3 1f 4e 90 dc 61 a4 d5 0f>,
    byteLength: 65
  },
  publicKeyInfo: PublicKeyInfo { signatureAlgorithm: undefined, publicKey: undefined },
  signatureValue: ArrayBuffer {
    [Uint8Contents]: <30 44 02 20 38 db 21 b6 b5 b7 c6 92 da ad a2 b6 2e bb 89 e5 a3 6e 3a 3c ce 66 1e 38 53 2b c9 ac c8 5c 34 1b 02 20 70 46 73 21 8f 77 b2 47 b5 51 ab 3c 3d 74 e1 ef 8f 4f 7e 3a e0 40 1d 53 54 26 65 3a aa 5e c2 a2>,
    byteLength: 70
  }
}
SignedDevconTicket {
  ticket: DevconTicket {
    devconId: 6n,
    ticketId: 417541561855n,
    ticketClass: 0n
  },
  commitment: ArrayBuffer {
    [Uint8Contents]: <04 07 02 50 ca 69 74 01 95 f9 31 f3 35 4c ca ba b8 72 4f 9d 98 e9 cd 8a d9 b0 8b 68 c1 e3 b3 9f ab 16 2c ef f4 a8 64 67 8b 1d 02 4d 78 64 77 3c 9f 0f fa 77 be 8d 54 6e 8d 83 34 88 48 41 03 c0 3a>,
    byteLength: 65
  },
  publicKeyInfo: PublicKeyInfo { signatureAlgorithm: undefined, publicKey: undefined },
  signatureValue: ArrayBuffer {
    [Uint8Contents]: <30 44 02 20 70 2c af bd e4 d3 d9 a3 45 b4 d4 70 c1 7f 26 62 b1 9d 8a 68 da f3 a1 6b b1 45 5f e7 86 31 8b 30 02 20 68 e3 f8 79 55 48 34 7e 71 33 c0 af f4 e5 43 77 23 86 dc 1c 54 ab 23 d5 40 eb 83 53 d3 da 0b da>,
    byteLength: 70
  }
}

And notice the last byte array is the signature, you can get the asn1 structure through this:

    0:d=0  hl=2 l=  68 cons: SEQUENCE          
    2:d=1  hl=2 l=  32 prim: INTEGER           :702CAFBDE4D3D9A345B4D470C17F2662B19D8A68DAF3A16BB1455FE786318B30
   36:d=1  hl=2 l=  32 prim: INTEGER           :68E3F8795548347E7133C0AFF4E543772386DC1C54AB23D540EB8353D3DA0BDA

So the first integer and the second integer are 𝑟 and 𝑠

You need to figure out a way of finding 𝑣 from a public key.

You can create a key like this:

$ openssl ecparam -name secp256k1 -genkey -noout -out key.pem

and read the value:

$ openssl ec -in key.pem -pubout -text
read EC key
Private-Key: (256 bit)
priv:
    05:89:22:6f:f7:e5:b6:bf:b7:79:57:af:0a:b2:66:
    9a:37:3c:80:7d:e1:e7:ee:bb:7f:51:53:ba:c0:79:
    0d:4b
pub:
    04:03:72:92:0b:c5:f2:92:ae:80:2f:f4:42:ed:e7:
    77:61:3a:af:13:ca:89:4b:9a:78:a1:01:d2:87:46:
    2e:17:a4:3e:b2:2d:dc:95:af:ae:31:5a:90:a2:0e:
    cb:1e:c4:56:97:2c:31:9a:c9:4c:00:b5:f0:66:dc:
    b1:dd:e5:64:02
ASN1 OID: secp256k1
writing EC key
-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEA3KSC8Xykq6AL/RC7ed3YTqvE8qJS5p4
oQHSh0YuF6Q+si3cla+uMVqQog7LHsRWlywxmslMALXwZtyx3eVkAg==
-----END PUBLIC KEY-----

Note that the public key here is not in ASN1 format! It's format is specified in SEC1 2.3.4 (if you want to sound professional, it's S.E.C. one, two, three, four) https://www.secg.org/sec1-v2.pdf#page=18

which is explained in plain English here: https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm

@jot2re how to get the 𝑣 value from this or the version with leading 04 stripped (which is Ethereum preferred method )

SmartLayer avatar Jan 07 '21 07:01 SmartLayer

Note that PR #89 changes the UseDevconTicket ticket to make signature optional and to use a Proof that does not include the riddle.

jot2re avatar Jan 07 '21 12:01 jot2re

I looked up a bit further in the SEC1 spec. Basically 3 bytes are allowed to prefix an elliptic curve point. The cases are as follows:

  1. 0x04; the point is uncompressed and includes the concatenation of the X coordinate followed by the Y coordinate.
  2. 0x02; the point is compressed and only includes the X coordinate and the parity of the Y coordinate is 0 (i.e. Y mod 2 =0).
  3. 0x03; the point is compressed and only includes the X coordinate and the parity of the Y coordinate is 1 (i.e. Y mod 2 =1).

Thus depending on whether 0x02 or 0x03 is the initial byte it is possible to uniquely determinate the correct value of Y from the X coordinate alone.

The big question is if the same logic is used for the v point in Ethereum. I googled a bit and finally found a description of how v is computed. According to (this discussion)[https://bitcoin.stackexchange.com/questions/38351/ecdsa-v-r-s-what-is-v] v=27+(y mod 2). Thus slightly different than the key encoding, but still easy to adapt.

jot2re avatar Jan 07 '21 13:01 jot2re

𝑦 mod 2

Nice! So @JamesSmartCell should be able to find 𝑣 value by just looking at the devcon issuer public key's last bit.

SmartLayer avatar Jan 08 '21 01:01 SmartLayer