0

I got following go-program:

package main

import (
    "fmt"
    "crypto/elliptic"
    "crypto/ecdsa"
    "crypto/sha512"
    "crypto/rand"
    "encoding/asn1"
)

func main() {
    message := []byte("TollJuhuWurstPizzaSchnellEssen")
    hash := sha512.Sum512(message)

//secp256r1
secp_priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
    panic(err)
}

r, s , err := ecdsa.Sign(rand.Reader, secp_priv, hash[:])
if err != nil {
    panic(err)
}

secpub := elliptic.Marshal(elliptic.P256(), secp_priv.PublicKey.X, secp_priv.PublicKey.Y)
fmt.Printf("secp256r1 pub: %#v\n", secpub)

secsig := elliptic.Marshal(elliptic.P256(), r, s)
fmt.Printf("secp256r1 sig %d: %#v\n",len(secsig), secsig)

x, y := elliptic.Unmarshal(elliptic.P256(), secpub)
secp_priv.PublicKey.X = x
secp_priv.PublicKey.Y = y

r2, s2 := elliptic.Unmarshal(elliptic.P256(), secsig[:])
fmt.Printf("r,s: %d %d\n", r, s)
fmt.Printf("r2,s2: %d %d\n", r2, s2)

valid := ecdsa.Verify(&secp_priv.PublicKey, hash[:], r, s)   //&secp_priv.PublicKey

fmt.Printf("secp256r1 verify1: %v\n", valid)

//SignASN1
asn1_sig , err := ecdsa.SignASN1(rand.Reader, secp_priv, hash[:])
if err != nil {
    panic(err)
}

fmt.Printf("secp256r1 sig_asn1 %d: %#v\n",len(asn1_sig), asn1_sig)
var buffer asn1.RawValue
_, err = asn1.Unmarshal(asn1_sig, &buffer)
if err != nil {
    panic(err)
}


fmt.Printf("secp256r1 unmarshal full sig_asn1 %d: %#v\n",len(buffer.FullBytes), buffer.FullBytes)
fmt.Printf("secp256r1 unmarshal sig_asn1 %d: %#v\n",len(buffer.Bytes), buffer.Bytes)

valid = ecdsa.VerifyASN1(&secp_priv.PublicKey, hash[:], asn1_sig)   //&secp_priv.PublicKey

fmt.Printf("secp256r1 verify1: %v\n", valid)



}

And I would like to know, how stuff is connected. What does it mean, to have an asn1 encoding. When I unmarshal it, i have 68byte slice. But when I unmarshal the r, s big.Int Values I got 65bytes (64bytes with 0x04 prefix byte). I also can not understand why r2 and s2 become nil. I can Unmarshal but not marshal the signature ... The operation is reversibel?

I would like to feed this library with signatures and public-keys: https://github.com/kmackay/micro-ecc/tree/static

But I dont know, what byteslice to take :(

Nikolai Ehrhardt
  • 570
  • 4
  • 14
  • ASN.1 is a family of encoding formats. The family has multiple formats BER, PER, DER, XER, etc. You need to know which format is used in the message to be able to encode/decode. The format is bidirectional, so you can encode and decode. Check this [post](http://luca.ntop.org/Teaching/Appunti/asn1.html) for more insights about ASN.1 – jordanvrtanoski Mar 13 '21 at 19:48
  • Its possible to unmarshal the asn1 sig with 'asn1.Unmarshal(asn1_sig, &buffer)', I think its DER format. But I got 68byte slice and signature from secp256r1 should be 64byte plus 0x04 prefix = 65byte. – Nikolai Ehrhardt Mar 13 '21 at 20:19
  • If you are getting 68 bytes and you expect 65, you definitely have wrong unmarshaling. This can be the difference in the format, so maybe it's not DER, or maybe your function is not unmarshaling DER. You need to research this further. – jordanvrtanoski Mar 13 '21 at 20:26
  • Your question covers several topics: The meaning of r and s in a signature, the different formats for EC public keys ((x,y) / compressed / uncompressed) and for signatures ((r,s) / ASN.1). This is probably too much for a single question. But you can find answers to all these topics in detail on the web, e.g. [here](https://cryptobook.nakov.com/digital-signatures/ecdsa-sign-verify-messages#ecdsa-sign), [here](https://crypto.stackexchange.com/q/70754), and [here](https://crypto.stackexchange.com/q/57731). – Topaco Mar 13 '21 at 22:07
  • At least I understood, that the asn1 encoding packs the r and s value... but I still dont know, what byteslice to use in the kmackay/micro-ecc lib. – Nikolai Ehrhardt Mar 13 '21 at 22:26

0 Answers0