Voice Biometrics & Application Security
by Moshe Yudkowsky

Listing One
<form id="samples">
    <block>
        <prompt>
          We need several samples of your voice. We'll ask you to repeat some
          numbers. Just repeat what we say, and speak naturally.
        </prompt>
    </block>
    <var name="thisSample" expr="fourDigitRandom()"/>
    <var name="thisSampleString" expr="fourDigitString(thisSample)"/>
    <register name="fourDigits_1" keyExpr="key"
                                 type="digits?length=4" mode="adapt">
        <prompt>
            Repeat after me: <break size="small" />
             <say-as type="number:digits">
             <value expr="thisSampleString"/> </say-as>
        </prompt>
        <noinput>
            <assign name="totalAttempts" expr="totalAttempts - 1" />
            <if cond="totalAttempts &lt;= 0">
                <goto next="#bounce"/>
            </if>
            <reprompt/>
        </noinput>
        <nomatch>
            <assign name="totalAttempts" expr="totalAttempts - 1" />
            <if cond="totalAttempts &lt;= 0">
                <goto next="#bounce"/>
            </if>
            <reprompt/>
        </nomatch>
        <filled>
            <var name="ok" expr="fourDigits_1 == thisSampleString" />
            <!-- check to see that we match -->
            <if cond="!ok">
                <clear namelist="fourDigits_1"/>
                <prompt>
                    We didn't get that, please try again. <break/>
                </prompt>
            <else/>
              <!-- reset for use by next "register" -->
              <assign name="thisSample" expr="fourDigitRandom()"/>
              <assign name="thisSampleString"
                              expr="fourDigitString(thisSample)"/>
              <assign name="totalAttempts" expr="3" />
            </if>
        </filled>



Listing Two
(a)
<form id="verification">
    <!-- Verify that the user is in the database -->
    <verify name="checkKey" keyExpr="key" type="digits?length=20" >
        <!-- make this a quick timeout -->
        <property name="timeout" value="1ms" />
        <!-- inaudible prompt -->
        <prompt>
            <break time="1ms" />
        </prompt>
        <!-- if there is a key we should timeout immediately and go here -->
        <catch event="noinput nomatch filled">
            <!-- assign value to field so Field Interpreter Algorithm
                                           doesn't bring us here again -->
            <assign name="checkKey" expr="'123'" />
            <goto nextitem="fourDigits_1" />
        </catch>
        <!-- if the key is not present, we end up here -->
        <catch event="error.verify.keynotfound error.badfetch">
            <!-- likely a bad key - send back to beginning of form -->
            <prompt>
                Sorry, we can't find account number
                <say-as type="number:digits"> <value expr="key" /> </say-as>.
                Let's try again.
            </prompt>
            <goto next="#getid" />
        </catch>
    </verify>


(b)
    <var name="thisSample" expr="fourDigitRandom()"/>
    <var name="thisSampleString" expr="fourDigitString(thisSample)"/>
    <var name="totalAttempts" expr="3" />

    <block>
        <prompt>
            We will ask you to repeat some numbers. Please speak naturally.
        </prompt>
    </block>

    <verify name="fourDigits_1" keyExpr="key" type="digits?length=4">

        <prompt>
            Repeat after me. <break size="small" />
             <say-as type="number:digits">
                                 <value expr="thisSampleString"/> </say-as>
        </prompt>

        <noinput>
            <assign name="totalAttempts" expr="totalAttempts - 1" />
            <if cond="totalAttempts &lt;= 0">
                <goto next="#denied" />
            <else/>
                <reprompt/>
            </if>
        </noinput>
        <nomatch>
            <!-- utterance did not match grammar. Spoof? -->
            <assign name="totalAttempts" expr="totalAttempts - 1" />
            <if cond="totalAttempts &lt;= 0">
                <goto next="#denied" />
            <else/>
                <reprompt/>
            </if>
        </nomatch>
        <filled>
            <assign name="totalAttempts" expr="totalAttempts - 1" />
            <!-- Too many attempts? Did we verify? -->
            <var name="check1" expr="totalAttempts &lt;= 0" />
            <var name="check2" expr="fourDigits_1 != thisSampleString" />
            <!-- check to see that we match -->
            <if cond="check1">
                <!-- too many attempts -->
                <goto next="#denied"/>
            <elseif cond="check2" />
                <!-- person spoke incorrect number. Spoof in progress? -->
                <clear namelist="fourDigits_1"/>
                <reprompt/>
            <elseif cond="fourDigits_1$.decision=='accepted'" />
                <goto next="#accepted" />
            <elseif cond="fourDigits_1$.decision=='rejected'"/>
                <goto next="#denied" />
            <else/>
                <!-- decision was "unsure." Proceed to next field -->
                <!-- reset attempts counter for use by next verify -->
                <assign name="totalAttempts" expr="3" />
            </if>
        </filled>


Listing Three
<form id="accepted">
    <block>
        <prompt>
            Your transaction has been accepted. Thank you. Goodbye.
        </prompt>
        <!-- Inform app of results -->
        <var name="resultString"
                     expr="'http://www.example.com/cgi-bin/success.cgi'" />
        <assign name="resultString"
                     expr="resultString+='?accountID='+key"/>
        <assign name="resultString"
                     expr="resultString+='&amp;outcome=success'"/>
        <prompt>
            <audio expr="resultString"/>
        </prompt>
    </block>
</form>





