cisco / go-hpke

Implementation of draft-irtf-cfrg-hpke
BSD 2-Clause "Simplified" License
30 stars 15 forks source link

Draft plumbing for test vector generation #5

Closed chris-wood closed 5 years ago

chris-wood commented 5 years ago

Some questions to consider:

  1. Does the "test then spit out vector" pattern make sense?
  2. Should the private key marshal interface be defined elsewhere?
  3. Should we add a method to the cipher suite interface that returns true/false for whether or not test vectors are supported? (They'd be true for all except SIKE, since we don't have a standard way to encode those private keys [that I'm aware of].)
bifurcation commented 5 years ago

Couple of comments here.

  1. We should try to be more complete, i.e., capture all computed values so that another implementor can compare at any point. We should also test the behavior of the multi-shot interface (i.e., that the counter / masking work properly).

0.1. that will mean the JSON struct should be something like:

type TestCase struct {
    // Crypto parameters
    mode Mode
    kem  KEMID
    kdf  KDFID
    aead AEADID

    // Private keys
    skRm, skEm []byte

    // Key schedule inputs
    pkRm, zz, enc, info, psk, pskID, pkIm  []byte

    // Values computed in KeySchedule
    ciphersuite, pskID_hash, info_hash, context, secret, key, nonce []byte

    // Encrypted values at various offsets
    pt0, aad0, ct0       []byte
    pt1, aad1, ct1       []byte
    pt256, aad256, ct256 []byte
}

0.2. You'll need a way to inject the preset ephemeral key. I would propose making a package-private (lower-case) method on the DHKEM interface that lets you set it into a private field in the DHKEM object, and then having Encap use it when set. Then you can make a Ciphersuite, set the ephemeral private key, and everything else should work as normal.

0.3. You'll need a way to collect the intermediate results from KeySchedule. I would propose making a package-private struct to hold these values, having private fields on EncryptContext/DecryptContext of that type, and having encryptionContext populate it with the results. (And while you're there, rename encryptionContext to keySchedule()!)

  1. We should keep the test vector generation separate from the actual testing. As long as they both run in a given instance, we'll know they're both correct. (Actually, we can also run the tests on the generated vectors.) And we'll want to do some different things for the test vectors vs. the real tests.

  2. It's find to have the marshal-privkey interfaces here.

  3. No, we should just have a list of cases that we want to generate test vectors for, which will be less than the full combinatorial explosion.