Browse Source

Support TOTP

master
Chris Smith 5 years ago
parent
commit
6b06ac381b

+ 11
- 0
app/src/main/java/com/chameth/yaotp/algos/Totp.kt View File

@@ -0,0 +1,11 @@
1
+package com.chameth.yaotp.algos
2
+
3
+import java.nio.ByteBuffer
4
+
5
+fun totp(key: ByteArray, startTime: Long = 0, step: Int = 30, currentTime: Long = currentTime(), length: Int = 6) = hotp(key, count(startTime, step, currentTime).toByteArray(), length)
6
+
7
+internal fun count(startTime: Long, step: Int, currentTime: Long) = (currentTime - startTime) / step
8
+
9
+internal fun currentTime() = System.currentTimeMillis() / 1000
10
+
11
+internal fun Long.toByteArray() = ByteBuffer.allocate(java.lang.Long.BYTES).putLong(this).array()

+ 48
- 0
app/src/test/java/com/chameth/yaotp/algos/TotpTest.kt View File

@@ -0,0 +1,48 @@
1
+package com.chameth.yaotp.algos
2
+
3
+import com.natpryce.hamkrest.assertion.assert
4
+import com.natpryce.hamkrest.equalTo
5
+import org.junit.Test
6
+
7
+class TotpTest {
8
+
9
+    private val rfcKey = "12345678901234567890".toByteArray()
10
+
11
+    @Test
12
+    fun testCount_withDefaultStepAndStart_andPastValues() {
13
+        assert.that(count(0, 30, 59), equalTo(1L))
14
+        assert.that(count(0, 30, 1111111109), equalTo(37037036L))
15
+        assert.that(count(0, 30, 1234567890), equalTo(41152263L))
16
+    }
17
+
18
+    @Test
19
+    fun testCount_withDefaultStepAndStart_andFutureDates() {
20
+        assert.that(count(0, 30, 2000000000), equalTo(66666666L))
21
+        assert.that(count(0, 30, 20000000000), equalTo(666666666L))
22
+    }
23
+
24
+    @Test
25
+    fun testCount_withCustomStepAndStart() {
26
+        assert.that(count(2000000000, 30, 4000000000), equalTo(66666666L))
27
+        assert.that(count(0, 60, 4000000000), equalTo(66666666L))
28
+    }
29
+
30
+    @Test
31
+    fun testLongToByteArray_withRfcValues() {
32
+        assert.that(1L.toByteArray().toHexString(), equalTo("0000000000000001"))
33
+        assert.that(37037036L.toByteArray().toHexString(), equalTo("00000000023523ec"))
34
+        assert.that(41152263L.toByteArray().toHexString(), equalTo("000000000273ef07"))
35
+        assert.that(666666666L.toByteArray().toHexString(), equalTo("0000000027bc86aa"))
36
+    }
37
+
38
+    @Test
39
+    fun testTotp_withRfcValues_usingSha1() {
40
+        assert.that(totp(rfcKey, 0, 30, 59, 8), equalTo(94287082))
41
+        assert.that(totp(rfcKey, 0, 30, 1111111109, 8), equalTo(7081804))
42
+        assert.that(totp(rfcKey, 0, 30, 1111111111, 8), equalTo(14050471))
43
+        assert.that(totp(rfcKey, 0, 30, 1234567890, 8), equalTo(89005924))
44
+        assert.that(totp(rfcKey, 0, 30, 2000000000, 8), equalTo(69279037))
45
+        assert.that(totp(rfcKey, 0, 30, 20000000000, 8), equalTo(65353130))
46
+    }
47
+
48
+}

Loading…
Cancel
Save