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"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Data struct {
|
type Input struct {
|
||||||
Operation string `json:"operation"`
|
Operation string `json:"operation"`
|
||||||
Arguments struct {
|
Arguments struct {
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
@ -90,6 +88,20 @@ func (ep *EdDSAPublicKey) UnmarshalJSON(in []byte) (e error) {
|
|||||||
return nil
|
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 (
|
const (
|
||||||
CURRENCY_LEN = 12
|
CURRENCY_LEN = 12
|
||||||
CURRENCY_LEN_STR = "12"
|
CURRENCY_LEN_STR = "12"
|
||||||
@ -246,10 +258,39 @@ func getValue(a byte) int {
|
|||||||
return -1
|
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) {
|
func (es *EdDSASignature) UnmarshalJSON(in []byte) (e error) {
|
||||||
var buf []byte
|
var buf []byte
|
||||||
|
|
||||||
// 1. decode crockford.base32
|
// Decode crockford.base32, the Taler flavour
|
||||||
if buf, e = crockfordDecode(bytes.Trim(in, `"`)); e != nil {
|
if buf, e = crockfordDecode(bytes.Trim(in, `"`)); e != nil {
|
||||||
return fmt.Errorf("couldn't decode EdDSASignature as crockford.base32: %v (%v)", e, string(in))
|
return fmt.Errorf("couldn't decode EdDSASignature as crockford.base32: %v (%v)", e, string(in))
|
||||||
} else if len(buf) != 64 {
|
} else if len(buf) != 64 {
|
||||||
@ -262,13 +303,31 @@ func (es *EdDSASignature) UnmarshalJSON(in []byte) (e error) {
|
|||||||
return nil
|
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
|
type RSAPublicKey rsa.PublicKey
|
||||||
|
|
||||||
// following gnunet/src/json/json_helper.c and gnunet/src/util/crypto_rsa.c
|
// following gnunet/src/json/json_helper.c and gnunet/src/util/crypto_rsa.c
|
||||||
func (ep *RSAPublicKey) UnmarshalJSON(in []byte) (e error) {
|
func (ep *RSAPublicKey) UnmarshalJSON(in []byte) (e error) {
|
||||||
var buf []byte
|
var buf []byte
|
||||||
|
|
||||||
// 1. decode crockford.base32
|
// 1. decode crockford.base32, the Taler flavour
|
||||||
if buf, e = crockfordDecode(bytes.Trim(in, `"`)); e != nil {
|
if buf, e = crockfordDecode(bytes.Trim(in, `"`)); e != nil {
|
||||||
return fmt.Errorf("couldn't decode EncodedRSAPublicKey as crockford.base32: %v (%v)", e, string(in))
|
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
|
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() {
|
func main() {
|
||||||
data := new(Data)
|
input := new(Input)
|
||||||
dec := json.NewDecoder(os.Stdin)
|
dec := json.NewDecoder(os.Stdin)
|
||||||
e := dec.Decode(data)
|
e := dec.Decode(input)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
log.Fatal(e)
|
log.Fatal(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
spew.Dump(data)
|
|
||||||
enc := json.NewEncoder(os.Stdout)
|
enc := json.NewEncoder(os.Stdout)
|
||||||
enc.SetIndent("Data:", " ")
|
enc.SetIndent("Input:", " ")
|
||||||
enc.Encode(data)
|
e = enc.Encode(input)
|
||||||
|
if e != nil {
|
||||||
|
log.Fatal(e)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user