output encoding of keys with crockford (the Taler flavor) done
This commit is contained in:
parent
03d90c406c
commit
63963e3fa5
@ -28,11 +28,9 @@ import (
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
type Data struct {
|
||||
type Input struct {
|
||||
Operation string `json:"operation"`
|
||||
Arguments struct {
|
||||
Version string `json:"version"`
|
||||
@ -90,6 +88,20 @@ func (ep *EdDSAPublicKey) UnmarshalJSON(in []byte) (e error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ep *EdDSAPublicKey) MarshalJSON() ([]byte, error) {
|
||||
enc, e := crockfordEncode([]byte(*ep))
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
|
||||
buf := make([]byte, len(enc)+2)
|
||||
buf[0] = '"'
|
||||
buf[len(buf)-1] = '"'
|
||||
copy(buf[1:], enc)
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
const (
|
||||
CURRENCY_LEN = 12
|
||||
CURRENCY_LEN_STR = "12"
|
||||
@ -246,10 +258,39 @@ func getValue(a byte) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
// Copy of GNUNET_STRINGS_data_to_string from gnunet/src/util/strings.c
|
||||
func crockfordEncode(in []byte) ([]byte, error) {
|
||||
const encTable = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
|
||||
|
||||
var (
|
||||
out []byte
|
||||
rpos, bits, vbit int
|
||||
)
|
||||
|
||||
for rpos < len(in) || vbit > 0 {
|
||||
if rpos < len(in) && vbit < 5 {
|
||||
bits = (bits << 8) | int(in[rpos]) // eat 8 more bits
|
||||
rpos++
|
||||
vbit += 8
|
||||
}
|
||||
if vbit < 5 {
|
||||
bits <<= (5 - vbit) // zero-padding
|
||||
if vbit != (len(in)*8)%5 {
|
||||
return nil, fmt.Errorf("vbit (%d) != (len(in)*8)%%5 (%d)", vbit, (len(in)*8)%5)
|
||||
}
|
||||
vbit = 5
|
||||
}
|
||||
vbit -= 5
|
||||
out = append(out, encTable[(bits>>vbit)&31])
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (es *EdDSASignature) UnmarshalJSON(in []byte) (e error) {
|
||||
var buf []byte
|
||||
|
||||
// 1. decode crockford.base32
|
||||
// Decode crockford.base32, the Taler flavour
|
||||
if buf, e = crockfordDecode(bytes.Trim(in, `"`)); e != nil {
|
||||
return fmt.Errorf("couldn't decode EdDSASignature as crockford.base32: %v (%v)", e, string(in))
|
||||
} else if len(buf) != 64 {
|
||||
@ -262,13 +303,31 @@ func (es *EdDSASignature) UnmarshalJSON(in []byte) (e error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (es *EdDSASignature) MarshalJSON() (b []byte, e error) {
|
||||
var buf = make([]byte, len(es.R)+len(es.S))
|
||||
copy(buf, es.R)
|
||||
copy(buf[len(es.R):], es.S)
|
||||
|
||||
enc, err := crockfordEncode(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b = make([]byte, len(enc)+2)
|
||||
b[0] = '"'
|
||||
b[len(b)-1] = '"'
|
||||
copy(b[1:], enc)
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
type RSAPublicKey rsa.PublicKey
|
||||
|
||||
// following gnunet/src/json/json_helper.c and gnunet/src/util/crypto_rsa.c
|
||||
func (ep *RSAPublicKey) UnmarshalJSON(in []byte) (e error) {
|
||||
var buf []byte
|
||||
|
||||
// 1. decode crockford.base32
|
||||
// 1. decode crockford.base32, the Taler flavour
|
||||
if buf, e = crockfordDecode(bytes.Trim(in, `"`)); e != nil {
|
||||
return fmt.Errorf("couldn't decode EncodedRSAPublicKey as crockford.base32: %v (%v)", e, string(in))
|
||||
}
|
||||
@ -296,16 +355,55 @@ func (ep *RSAPublicKey) UnmarshalJSON(in []byte) (e error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ep *RSAPublicKey) MarshalJSON() (b []byte, e error) {
|
||||
nb := ep.N.Bytes()
|
||||
eb := big.NewInt(int64(ep.E)).Bytes()
|
||||
if len(nb) > 2<<16-1 || len(eb) > 2<<16-1 {
|
||||
return nil, fmt.Errorf("values too large")
|
||||
}
|
||||
|
||||
buf := make([]byte, 4+len(nb)+len(eb))
|
||||
binary.BigEndian.PutUint16(buf, uint16(len(nb)))
|
||||
binary.BigEndian.PutUint16(buf[2:], uint16(len(eb)))
|
||||
copy(buf[4:], nb)
|
||||
copy(buf[4+len(nb):], eb)
|
||||
|
||||
enc, err := crockfordEncode(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b = make([]byte, len(enc)+2)
|
||||
b[0] = '"'
|
||||
b[len(b)-1] = '"'
|
||||
copy(b[1:], enc)
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
type Output []SignOperation
|
||||
|
||||
type SignOperation struct {
|
||||
Operation string `json:"operation"`
|
||||
Arguments struct {
|
||||
HDenumPub RSAPublicKey `json:"h_denum_pub"`
|
||||
AuditorSig EdDSASignature `json:"auditor_sig"`
|
||||
} `json:"arguments"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
data := new(Data)
|
||||
input := new(Input)
|
||||
dec := json.NewDecoder(os.Stdin)
|
||||
e := dec.Decode(data)
|
||||
e := dec.Decode(input)
|
||||
if e != nil {
|
||||
log.Fatal(e)
|
||||
}
|
||||
|
||||
spew.Dump(data)
|
||||
enc := json.NewEncoder(os.Stdout)
|
||||
enc.SetIndent("Data:", " ")
|
||||
enc.Encode(data)
|
||||
enc.SetIndent("Input:", " ")
|
||||
e = enc.Encode(input)
|
||||
if e != nil {
|
||||
log.Fatal(e)
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user