Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added implementation of FrodoKEM-640-SHAKE-CCA. #311

Merged
merged 10 commits into from
Feb 14, 2022

Conversation

xvzcf
Copy link
Contributor

@xvzcf xvzcf commented Jan 20, 2022

Also tagging @dstebila

@xvzcf xvzcf marked this pull request as ready for review January 20, 2022 21:52
Copy link
Member

@bwesterb bwesterb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Goutam! Looks good on first pass. Haven't checked the nitty-gritty details (yet).

kem/frodo/frodo640shake/frodo.go Outdated Show resolved Hide resolved
kem/frodo/frodo640shake/frodo.go Outdated Show resolved Hide resolved
kem/frodo/frodo640shake/matrix_shake.go Outdated Show resolved Hide resolved
kem/frodo/kat_test.go Outdated Show resolved Hide resolved
@armfazh armfazh added the new feature New functionality or module label Jan 24, 2022
kem/frodo/kat_test.go Outdated Show resolved Hide resolved
Copy link
Contributor

@claucece claucece left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! As this doesn't have the proofs yet, I'm leaving some details out that will be caught by the proofs.

}
}

func mulAddSAPlusE(out []uint16, s []uint16, e []uint16, A []uint16) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this is following more the 'C-like' syntax, you can always return the parameter instead of passing it as argument...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning slices might lead to allocations that can be prevented like this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(By passing an "out" slice, you make the caller responsible for the allocation.)

Copy link
Contributor

@armfazh armfazh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some minor changes

kem/frodo/doc.go Outdated Show resolved Hide resolved
kem/frodo/frodo640shake/frodo.go Outdated Show resolved Hide resolved
kem/frodo/frodo640shake/util.go Show resolved Hide resolved
kem/frodo/frodo640shake/noise.go Outdated Show resolved Hide resolved
kem/frodo/frodo640shake/frodo.go Outdated Show resolved Hide resolved
kem/frodo/frodo640shake/matrix_shake.go Outdated Show resolved Hide resolved
}

for j := 0; j < paramN; j++ {
A[(i*paramN)+j] = uint16(ARow[j*2]) | (uint16(ARow[(j*2)+1]) << 8)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here does it need reduction? if not, please add a comment why is not the case.

kem/frodo/frodo640shake/util.go Outdated Show resolved Hide resolved
}
}

func mulAddSBPlusE(out *[paramNbar * paramNbar]uint16, b *[paramN * paramNbar]uint16, s []uint16, e []uint16) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: we can make types to help on passing parameters correctly.
type nb_nb [paramNbar * paramNbar]uint16

must distinguish when cardinality coincides, e.g.
type n_nb [paramN * paramNbar]uint16
type nb_n [paramNbar * paramN]uint16

for j := 0; j < CDFTableLen-1; j++ {
gaussianSample += (CDFTable[j] - unifSample) >> 15
}
sampled[i] = ((-sign) ^ gaussianSample) + sign
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when sign=1, sampled gets sampled = (0xFF..FF ^ gaussianSample) + 1
is that final plus one part of the result?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, since flipBits(a) + 1 ≡ -a (mod 2^16) if a is 16 bit number, this just flips the sign of gaussianSample if sign = 1. Should I add a comment here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes please

@bwesterb bwesterb self-requested a review January 28, 2022 18:18
Copy link
Member

@bwesterb bwesterb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR and your previous changes.

I’ve gone through the code in detail on a plane. I would like some more documentation on what is going on and there is some low hanging fruit for optimization. I don’t think they’re blockers. I didn’t have internet on the plane, so I’m sorry that I’ll have to leave my comments as one big list.

  • note in comment that mbar is nbar
  • Note in comment that extractedbits is B
  • Reading/writing to shake never errors so we don’t need to check. Use _, _ = h.Read to prevent compiler warning.
  • Keygen
    • Note in comment that it’s S transpose, not S
    • Why is the seed as it is? Doesn’t seem to be defined in the FrodoKEM spec. Also, I’d say 128 bits should be enough.
    • The seed doesn’t contain seed_A (instead it contains z, with seed_A=shake(z)) so it doesn’t make sense for len_seedA to be part of the definition of KeySeedSize
    • You can remove the copy for shakeInputForSE by first writing a single byte and then the remainder.
    • It would be nice to add a test that the CDFTable indeed corresponds to Table 3 in the spec.
    • Although it’s all pretty standard, it wouldn’t hurt to add a comment or two what is going on in sample().
    • Please add a comment to note how you make a 2-dimensional array 1-dimensional. (Ie. Rows after each other.)
    • You’re not reducing in expandSeedIntoA. Probably that doesn’t matter but it deserves a comment that you’re leaving that out on purpose.
    • If you want you can get rid of some extra copy()s. For instance, you can sample directly into sk.matrixS
  • Encapsulation
    • This is probably premature optimization (— no need to look into it), but it might be faster to read one block of shake at a time and then call sample() on it before doing the next shake block. That reduces pressure on caches. Same goes for keygen.
  • Decapsulation
    • There is some shared code between encaps and decaps (generation of S’ and E’). Perhaps move that into a function?
    • Check whether Go turns ((1 << logQ)-1) into a constant or recomputes it.
  • Pack: This could be made much more efficient by packing eight at a time. Not a blocker.
  • Encode/DecodeMessage: we know the size of msg in advance. The go compiler is too stupid to realize so better make it see by using constant-size array.

xvzcf and others added 3 commits February 13, 2022 10:10
Co-authored-by: Armando Faz <armfazh@users.noreply.github.com>
Co-authored-by: Armando Faz <armfazh@users.noreply.github.com>
@armfazh armfazh merged commit e727ece into cloudflare:master Feb 14, 2022
@bwesterb
Copy link
Member

Thanks @xvzcf !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature New functionality or module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants