mozilla-services / go-cose

go library for CBOR Object Signing and Encryption (COSE)
Mozilla Public License 2.0
40 stars 18 forks source link

make I2OSP more constant time #40

Closed g-k closed 2 years ago

g-k commented 6 years ago

see discussion around https://github.com/mozilla-services/autograph/pull/76#discussion_r184970052

g-k commented 6 years ago

per https://github.com/mozilla-services/go-cose/pull/41 further investigation might help:

Need to profile this, but we could:

iterate through by byte instead
try to make the error checking constant time
find out if the big.Int.Bytes() call is accounting for the discrepancy

Also, the timing test is flaky.

g-k commented 6 years ago

Looks like the implementations of both Bytes and Sign methods are O(n) with int size (assuming the make([]byte, len(x.abs)*_S) and len(x.abs) are):

// Bytes returns the absolute value of x as a big-endian byte slice.
func (x *Int) Bytes() []byte {
    buf := make([]byte, len(x.abs)*_S)
    return buf[x.abs.bytes(buf):]
}

https://golang.org/src/math/big/int.go?s=10730:10758#L423

// Sign returns:
//
//  -1 if x <  0
//   0 if x == 0
//  +1 if x >  0
//
func (x *Int) Sign() int {
    if len(x.abs) == 0 {
        return 0
    }
    if x.neg {
        return -1
    }
    return 1
}

https://golang.org/src/math/big/int.go?s=575:599#L21

The a big int's Bits() that returns the little-endian Word slice method should be constant time.

franziskuskiefer commented 6 years ago

Ugh nasty. Bits looks like a good option.

hwine commented 2 years ago

We are no longer making changes to this repository. See README update for more information on the successor project.