package main import ( "crypto/rsa" "encoding/base32" "encoding/binary" "fmt" "math/big" ) type Keys struct { Denoms []DenomKey `json:"denoms"` MasterPublicKey MasterPublicKey `json:"master_public_key"` } type MasterPublicKey [256 / 8]byte type DenomKey struct { DenomPub EncodedRSAPublicKey `json:"denom_pub"` Value Amount `json:"value"` FeeWithdraw Amount `json:"fee_withdraw"` FeeDeposit Amount `json:"fee_deposit"` FeeRefresh Amount `json:"fee_refresh"` FeeRefund Amount `json:"fee_refund"` StampStart AbsoluteTime `json:"stamp_start"` StampExpireWithdraw AbsoluteTime `json:"stamp_expire_withdraw"` StampExpireDeposit AbsoluteTime `json:"stamp_expire_deposit"` StampExpireLegal AbsoluteTime `json:"stamp_expire_legal"` MasterSig EdDSASignature `json:"master_sig"` } type EncodedRSAPublicKey []byte const ( CURRENCY_LEN = 12 CURRENCY_LEN_STR = "12" ) type Amount struct { Value uint64 `json:"value"` Fraction uint32 `json:"fraction"` Currency [CURRENCY_LEN]byte `json:"currency"` } type AbsoluteTime uint64 type EdDSASignature struct { R [256 / 8]byte `json:"r"` S [256 / 8]byte `json:"s"` } // following gnunet/src/json/json_helper.c and gnunet/src/util/crypto_rsa.c func (ep *EncodedRSAPublicKey) Decode() (p rsa.PublicKey, e error) { var buf []byte // 1. decode base32 _, e = base32.StdEncoding.Decode(buf, *ep) if e != nil { return } // 2. parse header if len(buf) < 4 { e = fmt.Errorf("byte array too small for RSA public key header") return } modulus_length, public_exponent_length := binary.BigEndian.Uint16(buf[0:]), binary.BigEndian.Uint16(buf[2:]) if len(buf[4:]) != int(modulus_length)+int(public_exponent_length) { e = fmt.Errorf("byte array has wrong size according to encoded length's for modulus and public exponent") return } // 3. parse RSA public key // BUG! This is most likely wrong. // Consult _gcry_mpi_set_buffer from libgcrypt-1.9.4/mpi/mpicoder.c buf = buf[4:] p.N = big.NewInt(0).SetBytes(buf[:modulus_length]) buf = buf[modulus_length:] ex := big.NewInt(0).SetBytes(buf[:public_exponent_length]) // binary.BigEndian.Uint64 instead? if !ex.IsInt64() { e = fmt.Errorf("public exponent is not int64") return } p.E = int(ex.Int64()) return p, e } func main() { panic("nothing implemented yet.") }