Mirror of iOS, byte-identical by construction: both keys folded under one label when both sides have a PQ identity, classical pairs unchanged, and the exact digits pinned against an independent implementation so the two platforms cannot drift into showing different numbers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
54 lines
2.1 KiB
Kotlin
54 lines
2.1 KiB
Kotlin
package io.flamenet.e2e
|
|
|
|
import kotlin.test.Test
|
|
import kotlin.test.assertEquals
|
|
import kotlin.test.assertNotEquals
|
|
|
|
/**
|
|
* Audit H3: a substituted post-quantum identity must change the digits two
|
|
* people read aloud. Cross-platform: these values are the same ones the iOS
|
|
* SafetyNumberPQTests use, so a drift between the two engines fails here.
|
|
*/
|
|
class SafetyNumberPQTest {
|
|
private val aliceIK = ByteArray(32) { 0x11 }
|
|
private val bobIK = ByteArray(32) { 0x22 }
|
|
private val alicePQ = ByteArray(32) { 0xA1.toByte() }
|
|
private val bobPQ = ByteArray(32) { 0xB2.toByte() }
|
|
|
|
@Test fun `both sides see the same number`() {
|
|
assertEquals(
|
|
SafetyNumber.compute(aliceIK, alicePQ, bobIK, bobPQ),
|
|
SafetyNumber.compute(bobIK, bobPQ, aliceIK, alicePQ))
|
|
}
|
|
|
|
@Test fun `swapping the PQ identity changes the number`() {
|
|
assertNotEquals(
|
|
SafetyNumber.compute(aliceIK, alicePQ, bobIK, bobPQ),
|
|
SafetyNumber.compute(aliceIK, alicePQ, bobIK, ByteArray(32) { 0xEE.toByte() }))
|
|
}
|
|
|
|
@Test fun `a classical pair keeps the classical number`() {
|
|
assertEquals(SafetyNumber.compute(aliceIK, bobIK),
|
|
SafetyNumber.compute(aliceIK, null, bobIK, bobPQ))
|
|
assertEquals(SafetyNumber.compute(aliceIK, bobIK),
|
|
SafetyNumber.compute(aliceIK, alicePQ, bobIK, null))
|
|
}
|
|
|
|
/**
|
|
* The exact digits, from an INDEPENDENT implementation of the rule — the
|
|
* same constant the iOS suite pins. This is what makes both platforms
|
|
* agree with the spec rather than merely with each other; a silent drift
|
|
* would show two people different numbers and read as an attack.
|
|
*/
|
|
@Test fun `the number matches the independently computed value`() {
|
|
assertEquals(
|
|
"526042701003577849302816285461391061377406450730104222477184",
|
|
SafetyNumber.compute(aliceIK, alicePQ, bobIK, bobPQ))
|
|
}
|
|
|
|
@Test fun `the PQ number differs from the classical one`() {
|
|
assertNotEquals(SafetyNumber.compute(aliceIK, bobIK),
|
|
SafetyNumber.compute(aliceIK, alicePQ, bobIK, bobPQ))
|
|
}
|
|
}
|